From 0b84411960fbcd2ba77ae34e310594d829d1d3cb Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 25 May 2026 13:17:51 +0800 Subject: [PATCH 01/23] update tprocv2 explain and example code link --- docs/topics/example.rst | 12 ++++ docs/topics/index.rst | 12 ++++ docs/topics/tprocv2.rst | 128 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 docs/topics/example.rst create mode 100644 docs/topics/tprocv2.rst diff --git a/docs/topics/example.rst b/docs/topics/example.rst new file mode 100644 index 000000000..8be661b3c --- /dev/null +++ b/docs/topics/example.rst @@ -0,0 +1,12 @@ +Example code +============= + + +## Other examples of QICK measurement code, shared by QICK collaborators +tProc V1 base +* [IEEE Quantum Week 2023 QICK tutorial](https://github.com/openquantumhardware/QCE2023_public) +* [Connie Miao, Schuster Lab](https://github.com/conniemiao/slab_rfsoc_expts) +* [Chao Zhou, Hatlab](https://github.com/PITT-HATLAB/Hatlab_RFSOC) + +tProc V2 base +* [Jay, SQL Lab](https://github.com/JayChien04717/QickworksaceV2_proj) \ No newline at end of file diff --git a/docs/topics/index.rst b/docs/topics/index.rst index 068111449..7ac22cd3b 100644 --- a/docs/topics/index.rst +++ b/docs/topics/index.rst @@ -1,6 +1,15 @@ Specific topics =============== +This section collects focused explanations of concepts that come up when +writing QICK programs. Use these pages when you need background on timing, +frequency placement, pulse playback, generator configuration, units, clocking, +or the differences between assembly interfaces. + +For first-time setup and hardware bring-up, start with the :doc:`../quick_start` +guide instead. For class and function details, use the :doc:`../modules` API +reference. + .. toctree:: :maxdepth: 1 @@ -12,3 +21,6 @@ Specific topics units changing_fs reference_clock + tprocv2 + example_code + diff --git a/docs/topics/tprocv2.rst b/docs/topics/tprocv2.rst new file mode 100644 index 000000000..7451d98e3 --- /dev/null +++ b/docs/topics/tprocv2.rst @@ -0,0 +1,128 @@ +tProc v2 +======== + +tProc v2 is the latest generation of the QICK timed processor. It keeps the +same basic role as tProc v1--sequencing pulses, triggers, readout windows, and +feedback--but reorganizes both the firmware interface and the Python programming +model. + +This page is a short migration guide for users who already know tProc v1 and +want to understand the most important changes before writing tProc v2 programs. + + +Hardware sweeping +------------------ + +In tProc v1 programs, hardware sweeps often required an ``update()`` method +with explicit register math. For example, a gain sweep might update the +generator gain register with ``mathi()`` after each shot: + +.. code-block:: python + + class Program(RAveragerProgram): + def initialize(self): + self.q_rp = self.ch_page(self.cfg["qubit_ch"]) + self.r_gain = self.sreg(self.cfg["qubit_ch"], "gain") + + def body(self): + ... + + def update(self): + self.mathi(self.q_rp, self.r_gain, self.r_gain, "+", self.cfg["step"]) + + gain_list, avgi, avgq = prog.acquire(soc) + +tProc v2 provides higher-level sweep helpers. A program can declare a loop, +attach a swept parameter to that loop, and then query the compiled program for +the actual sweep points: + +.. code-block:: python + + class Program(AveragerProgramV2): + def _initialize(self, cfg): + self.add_loop("gainloop", cfg["steps"]) + self.add_pulse( + ch=cfg["qubit_ch"], + name="qubit_pulse", + style="const", + freq=cfg["freq"], + phase=0, + gain=QickSweep1D("gainloop", cfg["gain_start"], cfg["gain_stop"]), + length=cfg["length"], + ) + + def _body(self, cfg): + self.pulse(ch=cfg["qubit_ch"], name="qubit_pulse", t=0) + + iq_list = prog.acquire(soc, rounds=avg, progress=False) + gains = prog.get_pulse_param("qubit_pulse", "gain", as_array=True) + +Common swept parameters include: + +* Frequency +* Length +* Time +* Gain + +For frequency, length, and gain sweeps, use ``get_pulse_param()`` to query the +compiled sweep points: + +.. code-block:: python + + freqs = prog.get_pulse_param("qubit_pulse", "freq", as_array=True) + lengths = prog.get_pulse_param("qubit_pulse", "length", as_array=True) + gains = prog.get_pulse_param("qubit_pulse", "gain", as_array=True) + +For timing sweeps, tag the timed instruction and use ``get_time_param()``: + +.. code-block:: python + + times = prog.get_time_param("time_tag", "t", as_array=True) + +Timing +------- + +In tProc v2, pulse and trigger times are written in user-facing units, usually +microseconds. The Python API converts these values to tProc timing-clock cycles +when the program is compiled. + +Some tProc v1 timing names have also changed: + +* ``sync_all`` is now ``delay_auto()``. +* ``synci`` is now ``delay()``. +* ``wait_auto()`` keeps the same basic purpose, but works with the tProc v2 + timing model. + + +Play pulse +---------- + +In tProc v1, pulse parameters were often loaded into generator registers before +playing a pulse. In tProc v2, pulse settings are stored as waveforms in waveform +memory. A pulse can contain one or more waveforms, and playing a pulse sends the +corresponding waveform memory entry to the generator. + +This makes it easier to define several pulses during initialization and choose +which one to play in the program body. + +For example, a typical tProc v2 program does the following: + +* Declare the generator and readout channels. +* Add pulse definitions in ``_initialize()``. +* Play those pulses in ``_body()`` with ``pulse()``. +* Use ``trigger()`` and acquisition methods when readout data is needed. + +Units +----- + +tProc v2 APIs generally use natural units: + +* Times and pulse lengths are in microseconds. +* Frequencies are in MHz. +* Phases are in degrees. +* Gains are normalized values, usually from ``-1`` to ``1``. + +The compiler rounds these values to the nearest supported hardware +representation. To inspect the rounded values actually used by a compiled +program, use helper methods such as ``get_pulse_param()`` and +``get_time_param()``. From b5040a06801e6224fd5442d72b05d822b967a728 Mon Sep 17 00:00:00 2001 From: "QICK actions [bot]" <129547417+qickbot@users.noreply.github.com> Date: Mon, 25 May 2026 05:23:29 +0000 Subject: [PATCH 02/23] update version --- qick_lib/qick/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qick_lib/qick/VERSION b/qick_lib/qick/VERSION index a78d2d6b8..6d44296f8 100644 --- a/qick_lib/qick/VERSION +++ b/qick_lib/qick/VERSION @@ -1 +1 @@ -0.2.406 +0.2.409 From ae08e0ee825634c9b47f9f920b246affbdc44c3e Mon Sep 17 00:00:00 2001 From: Jay Date: Thu, 28 May 2026 13:44:17 +0800 Subject: [PATCH 03/23] Fix docs topics example link --- docs/topics/index.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/topics/index.rst b/docs/topics/index.rst index 7ac22cd3b..28c989132 100644 --- a/docs/topics/index.rst +++ b/docs/topics/index.rst @@ -22,5 +22,4 @@ reference. changing_fs reference_clock tprocv2 - example_code - + example From 31257aadd6e4e2829cff6ab863b55f597d5cfe07 Mon Sep 17 00:00:00 2001 From: Jay Date: Thu, 28 May 2026 13:53:22 +0800 Subject: [PATCH 04/23] Format docs example link lists --- docs/topics/example.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/topics/example.rst b/docs/topics/example.rst index 8be661b3c..663dd3db4 100644 --- a/docs/topics/example.rst +++ b/docs/topics/example.rst @@ -4,9 +4,11 @@ Example code ## Other examples of QICK measurement code, shared by QICK collaborators tProc V1 base + * [IEEE Quantum Week 2023 QICK tutorial](https://github.com/openquantumhardware/QCE2023_public) * [Connie Miao, Schuster Lab](https://github.com/conniemiao/slab_rfsoc_expts) * [Chao Zhou, Hatlab](https://github.com/PITT-HATLAB/Hatlab_RFSOC) tProc V2 base + * [Jay, SQL Lab](https://github.com/JayChien04717/QickworksaceV2_proj) \ No newline at end of file From c2a629447d0c234891bf862b4db2d328f25326e5 Mon Sep 17 00:00:00 2001 From: "QICK actions [bot]" <129547417+qickbot@users.noreply.github.com> Date: Thu, 28 May 2026 05:59:11 +0000 Subject: [PATCH 05/23] update version --- qick_lib/qick/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qick_lib/qick/VERSION b/qick_lib/qick/VERSION index 6d44296f8..da8e9784e 100644 --- a/qick_lib/qick/VERSION +++ b/qick_lib/qick/VERSION @@ -1 +1 @@ -0.2.409 +0.2.412 From 73ac2d78f50c17461cbc86bddb79108bddea5bc5 Mon Sep 17 00:00:00 2001 From: Jay Date: Thu, 28 May 2026 14:03:51 +0800 Subject: [PATCH 06/23] Adjust docs example list spacing --- docs/topics/example.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/topics/example.rst b/docs/topics/example.rst index 663dd3db4..3d84fc719 100644 --- a/docs/topics/example.rst +++ b/docs/topics/example.rst @@ -6,7 +6,9 @@ Example code tProc V1 base * [IEEE Quantum Week 2023 QICK tutorial](https://github.com/openquantumhardware/QCE2023_public) + * [Connie Miao, Schuster Lab](https://github.com/conniemiao/slab_rfsoc_expts) + * [Chao Zhou, Hatlab](https://github.com/PITT-HATLAB/Hatlab_RFSOC) tProc V2 base From 70ddd415fdce209af7c5b7c32085eb4932dff65e Mon Sep 17 00:00:00 2001 From: Horacio Arnaldi Date: Fri, 4 Sep 2026 16:46:08 -0500 Subject: [PATCH 07/23] docs: migrate to the tprocv2-era documentation tree (docs/source/) Replaces the pre-tprocv2 flat docs/ tree (tProc v1 + SG-v4 era: a single firmware.rst channel-assignment model, asmv1_cheatsheet.rst, no per-IP-core reference pages) with the restructured docs/source/ tree developed and audited in openquantumhardware/qick_internal. What's new, at a glance: - Full tProc v2 reference manual (tprocv2_trm.rst) plus a dedicated legacy tProc v1 page (tprocv1.rst) for users on older boards. - One reference page per readout/generator IP core (avg_buffer, mr_buffer_et, readout_v2, readout_dynamic, readout_pfb, kidsim, sg_v6, sg_v4, sg_int4_v2, sg_mux8, sg_mixmux8) plus family-overview pages (readout.rst, generators.rst) explaining which core to use for which experiment. - The 00-14 tutorial notebook series (nbsphinx-rendered). - A restructured "Software API" reference page with a real intro instead of a bare module list. - Corrected topics/ pages (asmv2_cheatsheet, timing, units, freq_matching, xcom, XCOM-commands, pyro4, playing_pulses, ...) -- several had fictional API calls or bit-encoding errors going back to the tProc v1 architecture that never got updated for v2. Every page was cross-checked against qick_lib source (and, for firmware-level claims, RTL) in the source repo before this migration; see qick_internal's fix-tprocv2-trm-docs branch history for the detailed per-page verification notes. Build infra changes: - docs/ -> docs/source/ (Sphinx source root now has its own subdirectory; docs/Makefile's SOURCEDIR already expected this). - .readthedocs.yaml: sphinx.configuration -> docs/source/conf.py, python.install requirements path unchanged (docs/requirements.txt, which already lists myst-parser and nbsphinx), added the `pandoc` apt package nbsphinx needs to render notebooks. - .gitignore: docs/_build|_autosummary -> docs/source/_build| _autosummary. Kept as-is (not part of the tprocv2 restructuring, independently maintained): papers.rst and its chart images -- the source repo's copy had fallen behind this repo's (missing 3 recently-added papers, the Qblox QICK box link, and the "At a glance" stats section) -- verified contact.rst and quick_start.rst have NOT drifted the same way before carrying those over unchanged. Verified with a full local sphinx-build against this repo's own qick_lib: 0 errors, only pre-existing warnings (a handful of docstring formatting issues in qick.py/rfboard.py/ tprocv2_assembler.py, unrelated to this migration). --- .gitignore | 4 +- .readthedocs.yaml | 6 +- docs/Makefile | 16 +- docs/conf.py | 352 - docs/firmware.rst | 75 - docs/index.rst | 94 - docs/modules.rst | 22 - docs/requirements.txt | 5 + docs/{ => source}/_static/custom.css | 0 docs/source/avg_buffer.rst | 237 + docs/source/conf.py | 200 + docs/{ => source}/contact.rst | 0 docs/source/firmware.rst | 515 ++ docs/source/generators.rst | 106 + .../images/papers/QICKpapers_count_Jan26.png | Bin .../images/papers/QICKpapers_count_May26.png | Bin .../papers/QICKpapers_qubit_types_Jan26.png | Bin .../papers/QICKpapers_qubit_types_May26.png | Bin .../QICKpapers_qubit_types_pie_May26.png | Bin .../papers/QICKpapers_scaling_Jan26_final.png | Bin .../papers/QICKpapers_scaling_May26.png | Bin .../papers/QICKpapers_scaling_pie_May26.png | Bin .../images/quick_start/Bootmodeswitch.png | Bin .../images/quick_start/Eafterwrite.PNG | Bin .../images/quick_start/boardpic_cartoon.PNG | Bin .../images/quick_start/ciscorouter.PNG | Bin .../images/quick_start/correctpynqversion.PNG | Bin .../images/quick_start/jupyternotebook1.PNG | Bin .../images/quick_start/jupyternotebook2.PNG | Bin .../images/quick_start/largeimagefile.PNG | Bin .../images/quick_start/port_forward.png | Bin .../quick_start/pscpfolderstructure.PNG | Bin .../quick_start/pullingdataofftheboard.PNG | Bin .../quick_start/pushingdatatotheboard.PNG | Bin .../images/quick_start/putty1.PNG | Bin .../images/quick_start/putty2.PNG | Bin .../images/quick_start/putty3.PNG | Bin .../images/quick_start/pynqstartup.PNG | Bin .../images/quick_start/pynqversion.PNG | Bin .../images/quick_start/static_ip.png | Bin .../images/quick_start/writetoEdrive.PNG | Bin .../images/topics/fig1_xcom_block_diag.png | Bin 0 -> 68682 bytes docs/source/images/topics/fig3_fanout_box.png | Bin 0 -> 498340 bytes docs/source/images/topics/fig4_xcom_sync.png | Bin 0 -> 705685 bytes .../images/topics/xcom_architecture.png | Bin 0 -> 57431 bytes docs/source/images/topics/xcom_cfg_if.png | Bin 0 -> 42856 bytes docs/source/images/topics/xcom_if.png | Bin 0 -> 17449 bytes .../images/topics/xcom_new_architecture.png | Bin 0 -> 107669 bytes .../images/topics/xcom_periph_timing.png | Bin 0 -> 115177 bytes docs/source/images/topics/xcom_reg_timing.png | Bin 0 -> 38557 bytes docs/source/images/topics/xcom_registers.png | Bin 0 -> 10656 bytes docs/source/images/topics/xcom_waves.png | Bin 0 -> 11400 bytes docs/source/index.rst | 185 + docs/source/kidsim.md | 472 ++ docs/source/modules.rst | 99 + docs/source/mr_buffer_et.rst | 402 ++ docs/{ => source}/papers.rst | 0 docs/{ => source}/quick_start.rst | 0 docs/source/readout.rst | 177 + docs/source/readout_dynamic.rst | 499 ++ docs/source/readout_pfb.rst | 455 ++ docs/source/readout_v2.rst | 160 + docs/source/sg_int4_v2.rst | 382 ++ docs/source/sg_mixmux8.rst | 358 + docs/source/sg_mux8.rst | 335 + docs/source/sg_v4.rst | 460 ++ docs/source/sg_v6.rst | 504 ++ docs/source/support_cores.rst | 452 ++ docs/source/topics/XCOM-commands.rst | 550 ++ docs/source/topics/asmv2_cheatsheet.rst | 264 + docs/{ => source}/topics/changing_fs.rst | 0 docs/source/topics/freq_matching.rst | 79 + docs/{ => source}/topics/gen_config.rst | 0 docs/source/topics/index.rst | 93 + docs/source/topics/playing_pulses.rst | 148 + docs/source/topics/pyro4.rst | 173 + docs/source/topics/readout_modes.rst | 96 + docs/{ => source}/topics/reference_clock.rst | 0 docs/source/topics/timing.rst | 202 + docs/source/topics/tutorials.rst | 116 + docs/source/topics/units.rst | 66 + docs/source/topics/xcom.rst | 485 ++ docs/source/tprocv1.rst | 642 ++ docs/source/tprocv2_trm.rst | 5868 +++++++++++++++++ .../source/tutorials/00_Getting_Started.ipynb | 353 + .../tutorials/01_Basic_Sequencing.ipynb | 497 ++ .../tutorials/02_Parameter_Sweeps.ipynb | 574 ++ .../source/tutorials/03_Advanced_Timing.ipynb | 616 ++ .../tutorials/04_Real_Time_Feedback.ipynb | 608 ++ .../05_Dynamic_Parameters_Subroutines.ipynb | 720 ++ .../06_Generators_And_Readouts.ipynb | 1594 +++++ .../07_Advanced_Generators_And_Readouts.ipynb | 2174 ++++++ .../tutorials/08_Hardware_Buffers.ipynb | 661 ++ .../09_Appendix_Tips_And_Limits.ipynb | 824 +++ .../10_Multi_Board_Synchronization.ipynb | 867 +++ ...11_Streaming_And_RealTime_Processing.ipynb | 2117 ++++++ .../12_DSP_Blocks_And_Correlators.ipynb | 717 ++ .../13_Custom_Firmware_Integration.ipynb | 765 +++ .../14_XCOM_Network_Synchronization.ipynb | 1067 +++ docs/source/tutorials/README.md | 112 + docs/topics/asmv1_cheatsheet.rst | 58 - docs/topics/freq_matching.rst | 20 - docs/topics/index.rst | 14 - docs/topics/playing_pulses.rst | 41 - docs/topics/timing.rst | 62 - docs/topics/units.rst | 13 - 106 files changed, 29065 insertions(+), 763 deletions(-) delete mode 100644 docs/conf.py delete mode 100644 docs/firmware.rst delete mode 100644 docs/index.rst delete mode 100644 docs/modules.rst rename docs/{ => source}/_static/custom.css (100%) create mode 100644 docs/source/avg_buffer.rst create mode 100644 docs/source/conf.py rename docs/{ => source}/contact.rst (100%) create mode 100644 docs/source/firmware.rst create mode 100644 docs/source/generators.rst rename docs/{ => source}/images/papers/QICKpapers_count_Jan26.png (100%) rename docs/{ => source}/images/papers/QICKpapers_count_May26.png (100%) rename docs/{ => source}/images/papers/QICKpapers_qubit_types_Jan26.png (100%) rename docs/{ => source}/images/papers/QICKpapers_qubit_types_May26.png (100%) rename docs/{ => source}/images/papers/QICKpapers_qubit_types_pie_May26.png (100%) rename docs/{ => source}/images/papers/QICKpapers_scaling_Jan26_final.png (100%) rename docs/{ => source}/images/papers/QICKpapers_scaling_May26.png (100%) rename docs/{ => source}/images/papers/QICKpapers_scaling_pie_May26.png (100%) rename docs/{ => source}/images/quick_start/Bootmodeswitch.png (100%) rename docs/{ => source}/images/quick_start/Eafterwrite.PNG (100%) rename docs/{ => source}/images/quick_start/boardpic_cartoon.PNG (100%) rename docs/{ => source}/images/quick_start/ciscorouter.PNG (100%) rename docs/{ => source}/images/quick_start/correctpynqversion.PNG (100%) rename docs/{ => source}/images/quick_start/jupyternotebook1.PNG (100%) rename docs/{ => source}/images/quick_start/jupyternotebook2.PNG (100%) rename docs/{ => source}/images/quick_start/largeimagefile.PNG (100%) rename docs/{ => source}/images/quick_start/port_forward.png (100%) rename docs/{ => source}/images/quick_start/pscpfolderstructure.PNG (100%) rename docs/{ => source}/images/quick_start/pullingdataofftheboard.PNG (100%) rename docs/{ => source}/images/quick_start/pushingdatatotheboard.PNG (100%) rename docs/{ => source}/images/quick_start/putty1.PNG (100%) rename docs/{ => source}/images/quick_start/putty2.PNG (100%) rename docs/{ => source}/images/quick_start/putty3.PNG (100%) rename docs/{ => source}/images/quick_start/pynqstartup.PNG (100%) rename docs/{ => source}/images/quick_start/pynqversion.PNG (100%) rename docs/{ => source}/images/quick_start/static_ip.png (100%) rename docs/{ => source}/images/quick_start/writetoEdrive.PNG (100%) create mode 100644 docs/source/images/topics/fig1_xcom_block_diag.png create mode 100644 docs/source/images/topics/fig3_fanout_box.png create mode 100644 docs/source/images/topics/fig4_xcom_sync.png create mode 100644 docs/source/images/topics/xcom_architecture.png create mode 100644 docs/source/images/topics/xcom_cfg_if.png create mode 100644 docs/source/images/topics/xcom_if.png create mode 100644 docs/source/images/topics/xcom_new_architecture.png create mode 100644 docs/source/images/topics/xcom_periph_timing.png create mode 100644 docs/source/images/topics/xcom_reg_timing.png create mode 100644 docs/source/images/topics/xcom_registers.png create mode 100644 docs/source/images/topics/xcom_waves.png create mode 100644 docs/source/index.rst create mode 100644 docs/source/kidsim.md create mode 100644 docs/source/modules.rst create mode 100644 docs/source/mr_buffer_et.rst rename docs/{ => source}/papers.rst (100%) rename docs/{ => source}/quick_start.rst (100%) create mode 100644 docs/source/readout.rst create mode 100644 docs/source/readout_dynamic.rst create mode 100644 docs/source/readout_pfb.rst create mode 100644 docs/source/readout_v2.rst create mode 100644 docs/source/sg_int4_v2.rst create mode 100644 docs/source/sg_mixmux8.rst create mode 100644 docs/source/sg_mux8.rst create mode 100644 docs/source/sg_v4.rst create mode 100644 docs/source/sg_v6.rst create mode 100644 docs/source/support_cores.rst create mode 100644 docs/source/topics/XCOM-commands.rst create mode 100644 docs/source/topics/asmv2_cheatsheet.rst rename docs/{ => source}/topics/changing_fs.rst (100%) create mode 100644 docs/source/topics/freq_matching.rst rename docs/{ => source}/topics/gen_config.rst (100%) create mode 100644 docs/source/topics/index.rst create mode 100644 docs/source/topics/playing_pulses.rst create mode 100644 docs/source/topics/pyro4.rst create mode 100644 docs/source/topics/readout_modes.rst rename docs/{ => source}/topics/reference_clock.rst (100%) create mode 100644 docs/source/topics/timing.rst create mode 100644 docs/source/topics/tutorials.rst create mode 100644 docs/source/topics/units.rst create mode 100644 docs/source/topics/xcom.rst create mode 100644 docs/source/tprocv1.rst create mode 100644 docs/source/tprocv2_trm.rst create mode 100644 docs/source/tutorials/00_Getting_Started.ipynb create mode 100644 docs/source/tutorials/01_Basic_Sequencing.ipynb create mode 100644 docs/source/tutorials/02_Parameter_Sweeps.ipynb create mode 100644 docs/source/tutorials/03_Advanced_Timing.ipynb create mode 100644 docs/source/tutorials/04_Real_Time_Feedback.ipynb create mode 100644 docs/source/tutorials/05_Dynamic_Parameters_Subroutines.ipynb create mode 100644 docs/source/tutorials/06_Generators_And_Readouts.ipynb create mode 100644 docs/source/tutorials/07_Advanced_Generators_And_Readouts.ipynb create mode 100644 docs/source/tutorials/08_Hardware_Buffers.ipynb create mode 100644 docs/source/tutorials/09_Appendix_Tips_And_Limits.ipynb create mode 100644 docs/source/tutorials/10_Multi_Board_Synchronization.ipynb create mode 100644 docs/source/tutorials/11_Streaming_And_RealTime_Processing.ipynb create mode 100644 docs/source/tutorials/12_DSP_Blocks_And_Correlators.ipynb create mode 100644 docs/source/tutorials/13_Custom_Firmware_Integration.ipynb create mode 100644 docs/source/tutorials/14_XCOM_Network_Synchronization.ipynb create mode 100644 docs/source/tutorials/README.md delete mode 100644 docs/topics/asmv1_cheatsheet.rst delete mode 100644 docs/topics/freq_matching.rst delete mode 100644 docs/topics/index.rst delete mode 100644 docs/topics/playing_pulses.rst delete mode 100644 docs/topics/timing.rst delete mode 100644 docs/topics/units.rst diff --git a/.gitignore b/.gitignore index 823a81765..5263f7ad1 100644 --- a/.gitignore +++ b/.gitignore @@ -37,8 +37,8 @@ build/ dist/ # Sphinx documentation -docs/_build/ -docs/_autosummary/ +docs/source/_build/ +docs/source/_autosummary/ ### macOS template # General diff --git a/.readthedocs.yaml b/.readthedocs.yaml index ede209771..955709c85 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -9,10 +9,12 @@ build: os: ubuntu-22.04 tools: python: "3.7" + apt_packages: + - pandoc # required by nbsphinx to render the tutorial notebooks -# Build documentation in the docs/ directory with Sphinx +# Build documentation in the docs/source/ directory with Sphinx sphinx: - configuration: docs/conf.py + configuration: docs/source/conf.py # Optionally build your docs in additional formats such as PDF and ePub formats: [] diff --git a/docs/Makefile b/docs/Makefile index e9e02455b..ecc450b60 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -15,9 +15,9 @@ endif # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source # the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext @@ -85,11 +85,11 @@ htmlhelp: qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + @echo "Build finished; now you can run \"qcollectiongenerator\" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/SphinxApidocTurorial.qhcp" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/project_name.qhcp" @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/SphinxApidocTurorial.qhc" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/project_name.qhc" applehelp: $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp @@ -104,8 +104,8 @@ devhelp: @echo @echo "Build finished." @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/SphinxApidocTurorial" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/SphinxApidocTurorial" + @echo "# mkdir -p $$HOME/.local/share/devhelp/project_name" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/project_name" @echo "# devhelp" epub: @@ -130,7 +130,7 @@ latexpdfja: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + @echo "platex/dvipdfmx finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100644 index ce009a86a..000000000 --- a/docs/conf.py +++ /dev/null @@ -1,352 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# Sphinx Apidoc Turorial documentation build configuration file, created by -# sphinx-quickstart on Fri Jan 8 20:52:00 2016. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys -import os -import pathlib - -## Make your modules available in sys.path -here = pathlib.Path(__file__).parent.resolve() -sys.path.insert(0, (here / '../qick_lib').resolve().as_posix()) -print(sys.path) - -def get_version(rel_path): - """ - qick_lib/qick/VERSION is a text file containing only the version number. - """ - return (here / rel_path).read_text().strip() - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.viewcode', - 'sphinx.ext.intersphinx', - 'sphinx.ext.mathjax', - ## Include autosymmary - 'sphinx.ext.autosummary', - 'sphinx.ext.napoleon', - 'sphinx.ext.extlinks', -] - -## Include Python objects as they appear in source files -## Default: alphabetically ('alphabetical') -autodoc_member_order = 'bysource' -## Default flags used by autodoc directives -autodoc_default_options = { - 'members': True, - 'show-inheritance': True, -} - -autodoc_mock_imports = ["pynq", "xrfclk", "xrfdc", "cffi", "Pyro4", "psutil"] - -## Generate autodoc stubs with summaries from code -autosummary_generate = True - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = 'qick' -copyright = 'openquantumhardware' -author = 'openquantumhardware' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = get_version("../qick_lib/qick/VERSION") -# The full version, including alpha/beta/rc tags. -release = version - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = 'en' - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'sphinx_rtd_theme' - -html_theme_options = { - 'logo_only': True, -} -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -html_logo = "../graphics/logoQICK.svg" - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# html_css_files = ['custom.css'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -#html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -## Sidebars configuration for alabaster theme - -html_sidebars = { - '**': [ - 'about.html', - 'navigation.html', - 'searchbox.html', - ] -} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. - -## I don't like links to page reST sources -html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr' -#html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# Now only 'ja' uses this config value -#html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -#html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'SphinxApidocTurorialdoc' - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', - -# Latex figure (float) alignment -#'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'SphinxApidocTurorial.tex', 'Sphinx Apidoc Turorial Documentation', - 'Roman Miroshnychenko', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'sphinxapidocturorial', 'Sphinx Apidoc Turorial Documentation', - [author], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'SphinxApidocTurorial', 'Sphinx Apidoc Turorial Documentation', - author, 'SphinxApidocTurorial', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False - -# Example configuration for intersphinx: refer to the Python standard library. -## Add Python version number to the default address to corretcly reference -## the Python standard library -intersphinx_mapping = {'python': ('https://docs.python.org/3.7', None), - 'pynq': ('https://pynq.readthedocs.io/en/v2.7.0', None), - 'numpy': ('https://numpy.org/doc/1.26', None), - } - -extlinks = {'repofile': ('https://github.com/openquantumhardware/qick/blob/main/%s', - '%s')} - -extlinks_detect_hardcoded_links = True - -linkcheck_ignore = [r'^https://blogs.keysight.com/', # gives 403 error - ] - -def setup(app): - app.add_css_file("custom.css" ) diff --git a/docs/firmware.rst b/docs/firmware.rst deleted file mode 100644 index 401724bd1..000000000 --- a/docs/firmware.rst +++ /dev/null @@ -1,75 +0,0 @@ -Firmware -======== - -This system includes the following components: - -* 1 output channels connected to PMOD0-3 and triggers for Readout Block. -* 7 output channels connected to DACs. -* 2 input channels connected to ADCs. -* 1 instance of tProcessor 64-bit instructions, 32-bit registers. - -Sampling frequency of ADC blocks is given by the variable ``soc.fs_adc``. Sampling frequency of DACs is stored in variable ``soc.fs_adc``. Fast-speed buffers were removed to save memory space. Raw data can be captured after x8 down-sampling. - -Output channels driving DACs use the updated Signal Generator V4, which has the possibility to upload I/Q envelopes, and uses 32-bit resolution for both frequency and phase. The format of the control word was updated accordingly to accomodate the bits. See example asm files for a detailed description of the fields. The maximum length of the I/Q envelopes is given by the variable ``soc.gens[i].MAX_LENGTH``. - -The readout block is actually built around two IPs: readout and average + buffer. Readout block includes a digital down-convertion, FIR filtering and decimation by 8. DDS frequency is configured using a register of the readout block and it is not intended to support real-time frequency hopping as in the Signal Generator side. After frequency shifting, filtering and decimation, the data stream is sent to the Average + Buffer block, which internally can store raw samples or perform the sum of the specified number of samples. The process is started with the external trigger signal, connected to output Channel 0 of tProcessor. The user can opt to route the input, the DDS wave or the frequency shifted signal to the FIR and decimation by 8 stage. This is done using a output selection register of the readout block. Regarding the buffering capabilities, the average section of the block has a buffer of ``soc.avg_bufs[i].AVG_MAX_LENGTH``. - -.. figure:: ../graphics/qsystem-readout.svg - :width: 100% - :align: center - -The tProcessor --------------- - -You also may want to learn more about how the QICK tProcessor works. -In this case, you can reference the `QICK assembly language documentation `_. -Note that this documentation is not up to date with the current version of the QICK tProcessor. -It is made available here as a learning tool for those interested in learning the principles of the tProcessor. -Those who have more specific questions can contact us. - -tProcessor channel assignment ------------------------------ - -tProcessor will be used to control the real-time operation of the experiment. Output channels (AXIS MASTER) of the tProcessor are assigned as follows: - -- Channel 0 : connected to PMOD0 0-3, and triggers for readout. Bits 0-3 are connected to PMOD0, bit 14 is connected to the trigger of the average/buffer block coming from the readout of ADC 224 CH0. Bit 15 is connected to the trigger of the average/buffer block coming from the readout of ADC 224 CH1. -- Channel 1 : connected to Signal Generator V4, which drives DAC 228 CH0. -- Channel 2 : connected to Signal Generator V4, which drives DAC 228 CH1. -- Channel 3 : connected to Signal Generator V4, which drives DAC 228 CH2. -- Channel 4 : connected to Signal Generator V4, which drives DAC 229 CH0. -- Channel 5 : connected to Signal Generator V4, which drives DAC 229 CH1. -- Channel 6 : connected to Signal Generator V4, which drives DAC 229 CH2. -- Channel 7 : connected to Signal Generator V4, which drives DAC 229 CH3. - -**Note** that if you are using the Xilinx XM500 daughter board that comes with the ZCU111, be aware of the filters that are put on that XM500 board: DAC 229 channels 0 and 1 are high pass filtered by a 1 GHz high pass filter, so ensure that signals coming out of channels 4 and 5 are at least 1 GHz. Also, DAC 229 channels 2 and 3 are low pass filtered by a 1 GHz low pass filter, so ensure that signals coming out of channels 6 and 7 are less than 1 GHz. DAC 228 channels 0, 1 and 2 are not filtered by the XM500 daughter board. - -The updated version of the tProcessor has 4 input (AXIS SLAVE) channels, which can be used for feedback. These are 64-bit, and the updated ``read`` instruction can specify channel number and upper/lower 32-bits to be read and written into an internal register. See example below on how to use this new capability. - -* Channel 0 : connected to readout 0, which is driven by ADC 224 CH0 -* Channel 1 : connected to readout 1, which is driven by ADC 224 CH1 - -**Note** that if you are using the Xilinx XM500 daughter board that comes with the ZCU111, be aware of the filters that are put on that XM500 board: ADC 224 channels 0 and 1 are low pass filtered by a 1 GHz low pass filter, so ensure that the signal coming into your XM500 board is less than 1 GHz so that it can be read in properly. - -Signal Generators are organized on the array ``soc.gens``, which is composed of 7 instances. Array index 0 is connected to tProcessor Channel 1, array index 1 is connected to tProcessor Channel 2, and so on. As way of example, let's assume the user needs to create a pulse on DAC 229 CH1 and DAC 229 CH3. These are connected to Channels 5, and 7 or the tProcessor, respectively. However, let's also assume that a gaussian envelope needs to be uploaded into the corresponding signal generator. ``soc.gens[3]`` drives DAC 229 CH1, and ``soc.gens[6]`` drives DAC 229 CH3. - -Similarly, average and buffer inputs blocks are organized on ``soc.avg_bufs`` array, which has two instances of the Average + Buffer block. The user can access them using index 0 and 1. - -Timing ------- - -The clock frequency of the FPGA is 384 MHz. Therefore, each clock cycle has a period of 2.6 ns. - -The DAC speed is ``384*16=6144 MHz`` (resolution ``~163 ps``) and the ADC speed is ``384*8 MHz`` but then the signal is decimated by a factor of ``8`` (resolution ``~2.6 ns``). The minimum DAC pulse length is 16 samples but if you want shorter pulses than that you can pad that pulse with zeros. - - -Firmware parameters -------------------- - -* Pulse memory length: 65536 per channel x2 (I,Q), i.e., 128k total -* Decimated ADC buffer length: 1024 samples per component (I,Q), 2k total -* Accumulated ADC buffer length: 16384 samples per component (I,Q), 32 k total -* tProc program memory length: 8k instructions of 64 bits, 64k Bytes total -* tProc data memory length: 4096 samples of 32 bits, 16k Bytes total -* tProc stack size: 256 samples of 32 bits, 1k Byte total -* Phase conversion from deg to reg: Phase resolution is 32-bit, that is :math:`\Delta \phi = 2 \pi /2^{32}` or :math:`360/2^{32}` -* Gain is 16-bit signed [-32768,32767] diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index 673bdcbd1..000000000 --- a/docs/index.rst +++ /dev/null @@ -1,94 +0,0 @@ -.. Sphinx Apidoc Turorial documentation master file, created by - sphinx-quickstart on Fri Jan 8 20:52:00 2016. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -.. toctree:: - :maxdepth: 2 - :hidden: - - quick_start - modules - topics/index - firmware - - contact - -Welcome to the QICK documentation! -================================================= - -.. figure:: ../graphics/QICK.jpg - :width: 100% - :align: center - -.. figure:: ../graphics/ZCU216Board.jpg - :width: 100% - :align: center - -The Quantum Instrumentation Control Kit (QICK for short) is a Xilinx RFSoC-based qubit controller which supports the direct synthesis of control and readout pulses. -The QICK consists of a digital board hosting an RFSoC (RF System-on-Chip) FPGA, custom firmware and software, and an optional companion custom-designed analog front-end board. -All of the schematics, firmware, and software are open-source and available on `Github `_. -We fully support the ZCU111, ZCU216, and RFSoC4x2 evaluation boards, and generally recommend using the newer generation of RFSoCs (ZCU216 and RFSoC4x2) for better overall performance. - -Getting started with QICK -------------------------- - -* First, for a global overview of the QICK and its capabilities, read `our instrumentation paper introducing the QICK `_. - -* If you have an RFSoC board and you want to configure it as a QICK board, follow :doc:`our quick start guide `. - -* After you configure your board, you can test it with `our demo notebooks `_. - These are intended as a tutorial. - The first demos explain important features of the QICK system and walk you through how to write working QICK programs. - The later demos provide examples of useful measurements you might make with the QICK. - We recommend that new users read and understand all of the demos. - -More examples and resources ---------------------------- - -Other examples and tutorials (compatibility with the current QICK software is not guaranteed): - -* `IEEE Quantum Week 2025 `_ -* `IEEE Quantum Week 2024 `_ -* `US QIS Summer School 2024 `_ -* `IEEE Quantum Week 2023 `_ - -Talk to us ------------- - -You can get in touch with the QICK core team and the user community through our :doc:`community contact channels `. - -QICK software -------------- - -`Source code `_ and :doc:`API documentation ` - -:doc:`/topics/index` - -QICK firmware -------------- - -Source code and instructions for compiling it yourself: `qick/firmware `_ - -:doc:`/firmware` - -Extensions beyond the core software and firmware ------------------------------------------------- - -If you want your board's state to persist between notebooks or scripts, you should install Pyro4 on your board and run QICK in a Pyro server: see `our Pyro4 demo notebooks `_ - -If you would like to save the instrument configuration for every measurement using `QCoDeS `_, you can also install `this QCoDeS driver `_. - -If you're interested in using QICK to control and read out NV centers or other quantum defects, you might be interested in `QICK-DAWG `_ which extends QICK with pulses and measurement programs specific to that application. - -If you want to use QICK for control and readout of solid-state spin qubits, `SpinQICK `_ extends the QICK API and provides high-level experiment code. - -QICK papers -------------- - -* For a list of academic papers produced using the QICK system, check out :doc:`our papers page ` - -.. toctree:: - :maxdepth: 2 - - papers diff --git a/docs/modules.rst b/docs/modules.rst deleted file mode 100644 index d4752818a..000000000 --- a/docs/modules.rst +++ /dev/null @@ -1,22 +0,0 @@ -Software API -============ - -.. autosummary:: - :toctree: _autosummary - - qick - qick.qick - qick.ip - qick.drivers.tproc - qick.drivers.generator - qick.drivers.readout - qick.helpers - qick.streamer - qick.pyro - qick.qick_asm - qick.asm_v1 - qick.parser - qick.averager_program - qick.asm_v2 - qick.tprocv2_assembler - qick.rfboard diff --git a/docs/requirements.txt b/docs/requirements.txt index f8cfa6adc..176b84bf6 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,8 @@ numpy>=1.14.2 tqdm +sphinx sphinx-rtd-theme +nbsphinx +myst-parser +ipython +ipykernel diff --git a/docs/_static/custom.css b/docs/source/_static/custom.css similarity index 100% rename from docs/_static/custom.css rename to docs/source/_static/custom.css diff --git a/docs/source/avg_buffer.rst b/docs/source/avg_buffer.rst new file mode 100644 index 000000000..d47ffa3e5 --- /dev/null +++ b/docs/source/avg_buffer.rst @@ -0,0 +1,237 @@ +======================================================== +Averager + Buffer (axis_avg_buffer) - QICK Firmware +======================================================== + +.. contents:: + :local: + :depth: 2 + +The **Averager + Buffer** (``axis_avg_buffer``) is the IP block that sits +downstream of a readout (:doc:`/readout`) and turns its decimated I/Q stream +into the two kinds of data a QICK program can pull back over PS-PL DMA: +accumulated points (:meth:`.AcquireMixin.acquire`) and raw decimated +waveforms (:meth:`.AcquireMixin.acquire_decimated`) -- see +:doc:`topics/readout_modes` for the software-level distinction. The module +lives in the ``qick`` firmware repository under +``firmware/ip/axis_avg_buffer/`` and is exposed to Python through +``qick.drivers.readout.AxisAvgBuffer`` (and its ``V1pt1``/``V1pt2``/ +``AxisWeightedBuffer`` subclasses). + +-------------------------------------------------------------------- +1. General Description +-------------------------------------------------------------------- + +``axis_avg_buffer`` (``axis_avg_buffer.v``) takes one AXI-Stream input +(``s_axis``, the readout's decimated I/Q, ``2*B`` bits wide -- I in the low +``B`` bits, Q in the high ``B`` bits) and drives three independent output +streams from a single hardware ``trigger``: + +* **m0_axis** -- the *averaged* buffer: one accumulated (I, Q) point per + trigger, stored in a dedicated BRAM and DMA'd out on request. This is what + ``acquire()`` reads. +* **m1_axis** -- the *raw* buffer: every decimated sample captured + individually during the trigger window, stored in a second BRAM and DMA'd + out separately. This is what ``acquire_decimated()`` reads. +* **m2_axis** -- the same accumulated point as m0, but streamed out live (via + a small async FIFO, no BRAM round-trip) instead of waiting for a DMA + request. This feeds an input port of the tProcessor directly, for + real-time feedback (e.g. thresholding a readout result to steer the next + part of the program without going through software). + +Internally the block is two independent, symmetric halves -- ``avg_top`` +(drives m0 + m2) and ``buffer_top`` (drives m1) -- both built from the same +pattern: a small FSM that writes captured/accumulated data into a dual-port +BRAM, and a second FSM (``data_reader``) that reads it back out over AXI-Stream +on request. Both halves share the same ``trigger`` and are independently +enabled/addressed/sized -- you can run one without the other. + +-------------------------------------------------------------------- +2. Synthesis Parameters +-------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + :widths: 20 15 55 + + * - Parameter + - RTL Default + - Description + * - ``B`` + - 16 + - Bit width of one I or one Q sample coming in on ``s_axis`` + (``s_axis_tdata`` is ``2*B`` bits: I in bits ``[B-1:0]``, Q in bits + ``[2*B-1:B]``). + * - ``N_AVG`` + - 10 + - Address width of the averaged-buffer BRAM. Depth (max number of + accumulated points that can be stored per trigger burst) is + ``2**N_AVG``. Exposed to Python as ``cfg['avg_maxlen']``. + * - ``N_BUF`` + - 10 + - Address width of the raw-buffer BRAM. Depth (max number of raw + samples per trigger) is ``2**N_BUF``. Exposed to Python as + ``cfg['buf_maxlen']``. + +The accumulator itself is ``2*B`` bits signed per component (``acc_i``, +``acc_q``), and the averaged-buffer word is ``4*B`` bits (``{acc_q, acc_i}``, +i.e. 64 bits total for the default ``B=16``) -- this is why the Python driver +reads ``avg_buff`` as ``np.int64`` and ``buf_buff`` (``2*B`` bits per raw +sample) as ``np.int32``/``np.int16`` (see :ref:`avgbuf-python`). Real board +configurations typically instantiate larger ``N_AVG``/``N_BUF`` than the RTL +default (see ``soc.cfg['readouts'][i]['avg_maxlen']``/``buf_maxlen']`` for +the values on your board -- read them at runtime rather than assuming a +number, since they vary by board and by readout channel). + +-------------------------------------------------------------------- +3. Averaged Buffer Datapath (m0_axis / m2_axis) +-------------------------------------------------------------------- + +The ``avg`` FSM (``avg.sv``) has two mutually exclusive modes, selected by +``AVG_PHOTON_MODE_REG``: + +* **Accumulate mode** (``AVG_PHOTON_MODE_REG=0``, the default): on every + valid input sample while triggered, ``acc_i += I`` and ``acc_q += Q`` + (plain running sums, no length normalization in hardware -- that division + happens in software, see :meth:`.AcquireMixin.acquire`'s length + normalization). After ``AVG_LEN_REG`` samples, the accumulated + ``{acc_q, acc_i}`` word is written to BRAM at ``AVG_ADDR_REG`` and the FSM + waits for the next trigger (auto-incrementing the write address each time, + so consecutive triggers fill consecutive slots). +* **Edge-counter / "photon" mode** (``AVG_PHOTON_MODE_REG=1``): instead of + summing I/Q, the block compares the I component against two signed + thresholds (``AVG_H_THRSH_REG``, ``AVG_L_THRSH_REG``) and counts *rising + edges* through the high threshold (a Schmitt-trigger-style hysteresis: a + new edge only counts once I has dropped back below the low threshold and + risen through the high threshold again). This is the ``EDGE_COUNTER`` + feature the Python driver flags via ``cfg['has_edge_counter']`` -- useful + for photon-counting / single-photon-detector style readouts where you want + a pulse count rather than an integrated amplitude. + +FSM states: ``INIT -> START -> TRIGGER -> AVG -> QOUT -> WRITE_MEM -> +WAIT_TRIGGER -> (TRIGGER or START)``. ``AVG_START_REG`` gates whether the +block is armed at all; the actual capture only begins once the external +``trigger`` pulse arrives while armed, and the FSM returns to +``WAIT_TRIGGER``/``TRIGGER`` afterward so back-to-back triggers (e.g. once +per rep in a loop) each get their own BRAM slot without re-arming from +software. + +The averaged-buffer BRAM is read out by a ``data_reader`` FSM controlled by +``AVG_DR_START_REG``/``AVG_DR_ADDR_REG``/``AVG_DR_LEN_REG``, independent of +the write side -- you can read back completed points while the FSM is +capturing new ones elsewhere in the buffer. ``m2_axis`` taps the same +accumulated word through a small async FIFO the instant it's computed +(``QOUT_ST``/``WRITE_MEM_ST``), without going through the BRAM/data_reader +path at all -- that's what makes it usable for low-latency in-program +feedback. + +-------------------------------------------------------------------- +4. Raw Buffer Datapath (m1_axis) +-------------------------------------------------------------------- + +``buffer_top``/``buffer.sv`` is structurally the same pattern (FSM + BRAM + +``data_reader``) but simpler: every individual decimated (I, Q) sample seen +while triggered (governed by ``BUF_START_REG``/``BUF_ADDR_REG``/ +``BUF_LEN_REG``) is written to BRAM as-is, one sample per address, no +accumulation. Read-back uses its own independent +``BUF_DR_START_REG``/``BUF_DR_ADDR_REG``/``BUF_DR_LEN_REG`` registers. This +is the raw time-domain waveform :meth:`.AcquireMixin.acquire_decimated` +returns. + +-------------------------------------------------------------------- +5. Register Map +-------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + :widths: 25 15 60 + + * - Register + - Width + - Description + * - ``AVG_START_REG`` + - 1 bit + - 0: averager disabled. 1: armed, waiting for/capturing on ``trigger``. + * - ``AVG_ADDR_REG`` + - ``N_AVG`` bits + - BRAM write address for the next accumulated point. + * - ``AVG_LEN_REG`` + - 32 bits + - Number of input samples to accumulate before writing out one point. + * - ``AVG_PHOTON_MODE_REG`` + - 1 bit + - 0: accumulate I/Q. 1: edge-counter mode (see above). + * - ``AVG_H_THRSH_REG`` / ``AVG_L_THRSH_REG`` + - ``B`` bits (signed) + - High/low thresholds for edge-counter mode. + * - ``AVG_DR_START_REG`` + - 1 bit + - 1: stream accumulated data out on ``m0_axis``. + * - ``AVG_DR_ADDR_REG`` / ``AVG_DR_LEN_REG`` + - ``N_AVG`` bits + - Start address / sample count for the ``m0_axis`` read-back. + * - ``BUF_START_REG`` + - 1 bit + - 0: raw buffer disabled. 1: armed, waiting for/capturing on ``trigger``. + * - ``BUF_ADDR_REG`` / ``BUF_LEN_REG`` + - ``N_BUF`` bits + - BRAM write address / number of raw samples to capture. + * - ``BUF_DR_START_REG`` + - 1 bit + - 1: stream raw data out on ``m1_axis``. + * - ``BUF_DR_ADDR_REG`` / ``BUF_DR_LEN_REG`` + - ``N_BUF`` bits + - Start address / sample count for the ``m1_axis`` read-back. + +.. _avgbuf-python: + +-------------------------------------------------------------------- +6. Python Interface +-------------------------------------------------------------------- + +Most QICK programs never call this driver directly -- :meth:`.AcquireMixin.acquire` +and :meth:`.AcquireMixin.acquire_decimated` drive it for you. Use the driver +directly only when you need low-level control (custom triggering schemes, +reading a buffer mid-experiment, etc.). It is reached as +``soc.avg_bufs[readout_index]``. + +.. code-block:: python + + from qick import * + + soc = QickSoc() + buf = soc.avg_bufs[0] + + # Set the downconversion frequency on the readout that feeds this buffer. + buf.set_freq(100.0, gen_ch=0) # MHz + + # --- Accumulated (averaged) capture --- + buf.config_avg(address=0, length=1) # 1 accumulated point per trigger + buf.enable(avg=True, buf=False) + # ... run your tProc program, which fires `trigger` ... + iq = buf.transfer_avg(address=0, length=1) # -> shape (1, 2): [[I, Q]] + + # --- Raw (decimated) capture --- + buf.config_buf(address=0, length=1024) + buf.enable(avg=False, buf=True) + # ... run your tProc program ... + iq = buf.transfer_buf(address=0, length=1024) # -> shape (1024, 2) + +``transfer_avg``/``transfer_buf`` return the data already reshaped as +``(n_samples, 2)`` arrays of raw integers (not length-normalized or +offset-corrected -- that's what :meth:`.AcquireMixin._average_buf` and +:meth:`.AcquireMixin._ro_offset` do on top of this). Both work around a +known IP bug (fixed in newer IP versions, tracked by the driver's +``FIRST_OUT_SAMPLE_BUG_FIX`` flag) where the first sample of a transfer +always reads back as the sample at address 0, by silently requesting two +extra samples and discarding them. + +Related Documentation +---------------------- + +* :doc:`/readout` -- the readout block that feeds this buffer's ``s_axis``. +* :doc:`topics/readout_modes` -- ``acquire()`` vs. ``acquire_decimated()``. +* :doc:`/tprocv2_trm` -- the tProcessor trigger that starts a capture, and + the m2_axis feedback port. +* :doc:`/mr_buffer_et` -- the alternate multi-rate buffer used for + DDR4/streaming readout of the *undecimated* data stream, as opposed to + this block's decimated raw buffer. diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 000000000..d71847b99 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# QICK documentation build configuration file +# +# This file is execfile()d with the current directory set to its +# containing dir. + +import sys +import os +import pathlib +import shutil + +#Check if Pandoc is installed +if shutil.which('pandoc') is None: + import warnings + warnings.warn( + "pandoc not found. Install it with: sudo apt install pandoc (Linux) " + "or brew install pandoc (macOS). Required for notebook conversion." + ) + +# -- Path setup -------------------------------------------------------------- + +# Make your modules available in sys.path +here = pathlib.Path(__file__).parent.resolve() +sys.path.insert(0, (here / '../../qick_lib').resolve().as_posix()) +print(f"Python path: {sys.path[0]}") + +def get_version(rel_path): + """ + qick_lib/qick/VERSION is a text file containing only the version number. + """ + return (here / rel_path).read_text().strip() + +# -- Project information ----------------------------------------------------- + +project = 'QICK' +copyright = 'OpenQuantumHardware' +author = 'OpenQuantumHardware' + +# The short X.Y version. +version = get_version("../../qick_lib/qick/VERSION") +# The full version, including alpha/beta/rc tags. +release = version + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.viewcode', + 'sphinx.ext.intersphinx', + 'sphinx.ext.mathjax', + 'sphinx.ext.autosummary', + 'sphinx.ext.napoleon', + 'sphinx.ext.extlinks', + 'nbsphinx', # For Jupyter notebooks + 'myst_parser', # For Markdown files +] + +# nbsphinx configuration +nbsphinx_execute = 'never' # Don't execute notebooks during build +nbsphinx_allow_errors = True # Continue even if notebooks have errors +nbsphinx_timeout = 120 # Timeout for notebook execution (seconds) + +# autodoc configuration +autodoc_member_order = 'bysource' +autodoc_default_options = { + 'members': True, + 'show-inheritance': True, + 'inherited-members': True, + 'special-members': '__init__', + 'undoc-members': True, + 'exclude-members': '__weakref__' +} + +# Mock imports for modules that are not available during documentation build +autodoc_mock_imports = ["pynq", "xrfclk", "xrfdc", "cffi", "Pyro4", "psutil"] + +# Generate autodoc stubs with summaries from code +autosummary_generate = True + +# Add any paths that contain templates here +templates_path = ['_templates'] + +# The suffix(es) of source filenames +source_suffix = { + '.rst': 'restructuredtext', + '.md': 'markdown', + #'.ipynb': 'jupyter_notebooks', +} + +# MyST (Markdown) extensions -- dollarmath lets .md pages use $...$/$$...$$ for equations +myst_enable_extensions = ['dollarmath'] + +# The master toctree document +master_doc = 'index' + +# The language for content +language = 'en' + +# List of patterns to ignore when looking for source files +exclude_patterns = [ + '_build', + 'Thumbs.db', + '.DS_Store', + '**.ipynb_checkpoints', # Exclude Jupyter checkpoint files +] + +# The name of the Pygments (syntax highlighting) style +pygments_style = 'sphinx' + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML pages +html_theme = 'sphinx_rtd_theme' + +# Theme options +html_theme_options = { + 'logo_only': True, + 'navigation_depth': 4, +} + +# The name of an image file to place at the top of the sidebar +html_logo = "../../graphics/logoQICK.svg" + +# Add any paths that contain custom static files +html_static_path = ['_static'] + +# Custom CSS files +html_css_files = ['custom.css'] + +# If true, links to the reST sources are added to the pages +html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer +html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer +html_show_copyright = True + +# Output file base name for HTML help builder +htmlhelp_basename = 'QICKdoc' + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + 'papersize': 'letterpaper', + 'pointsize': '10pt', + 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files +latex_documents = [ + (master_doc, 'QICK.tex', 'QICK Documentation', + author, 'manual'), +] + +# -- Options for manual page output ------------------------------------------ + +man_pages = [ + (master_doc, 'qick', 'QICK Documentation', + [author], 1) +] + +# -- Options for Texinfo output ---------------------------------------------- + +texinfo_documents = [ + (master_doc, 'QICK', 'QICK Documentation', + author, 'QICK', 'Quantum Instrumentation Control Kit', + 'Miscellaneous'), +] + +# -- Intersphinx configuration ----------------------------------------------- + +intersphinx_mapping = { + 'python': ('https://docs.python.org/3.10', None), + 'numpy': ('https://numpy.org/doc/stable', None), + 'pynq': ('https://pynq.readthedocs.io/en/latest', None), +} + +# -- Extlinks configuration -------------------------------------------------- + +extlinks = { + 'repofile': ('https://github.com/openquantumhardware/qick/blob/main/%s', '%s'), +} + +extlinks_detect_hardcoded_links = True + +# -- Linkcheck configuration ------------------------------------------------ + +linkcheck_ignore = [ + r'^https://blogs.keysight.com/', # gives 403 error + r'^http://localhost', # ignore local servers +] + +# -- Custom CSS ------------------------------------------------------------- + +def setup(app): + app.add_css_file("custom.css") diff --git a/docs/contact.rst b/docs/source/contact.rst similarity index 100% rename from docs/contact.rst rename to docs/source/contact.rst diff --git a/docs/source/firmware.rst b/docs/source/firmware.rst new file mode 100644 index 000000000..6291cce9c --- /dev/null +++ b/docs/source/firmware.rst @@ -0,0 +1,515 @@ +Firmware +======== + +This page provides an overview of the QICK firmware components. + +System Overview +--------------- + +The QICK firmware includes the following components: + +* **tProcessor v2** - Real-time co-processor for sequencing and feedback +* **Signal Generator v6 (SG-v6)** - DDS-based waveform generators for DAC outputs +* **Readout System** - ADC data acquisition with DDC, filtering, and averaging + +.. list-table:: + :header-rows: 1 + + * - Component + - Quantity + - Documentation + * - tProcessor v2 + - 1 instance (64-bit instructions, 32-bit registers) + - :doc:`/tprocv2_trm` + * - Signal generators + - Board-dependent -- each board's standard firmware provisions its own + mix of :doc:`/sg_v6`, :doc:`/sg_int4_v2`, :doc:`/sg_mixmux8`, + :doc:`/sg_mux8`; see :ref:`std-firmware-per-board` + - :doc:`/generators`, :doc:`/sg_v6` + * - Readouts + - Board-dependent -- single-tone (:doc:`/readout_v2`, + :doc:`/readout_dynamic`) and/or channelized (:doc:`/readout_pfb`); + see :ref:`std-firmware-per-board` + - :doc:`/readout`, :doc:`/readout_dynamic`, :doc:`/readout_pfb`, + :doc:`/avg_buffer` + * - tProc trigger outputs (``trig_N_o`` pins) + - Board-dependent single-bit pins -- PMOD bits plus one per averaging + buffer, plus DDR4/multi-rate-buffer triggers where present; see + :ref:`tproc-ports` + - :doc:`/tprocv2_trm` + +Sampling frequency of ADC blocks is given by the variable ``soc.fs_adc``. +Sampling frequency of DACs is stored in variable ``soc.fs_dac``. +Fast-speed buffers were removed to save memory space. Raw data can be captured after x8 down-sampling. + +Signal Generator v6 (SG-v6) +--------------------------- + +Output channels driving DACs use the **Signal Generator v6**, which has the following features: + +* Supports uploading I/Q envelopes +* 32-bit resolution for both frequency and phase +* Configurable DDS with streaming mode (frequency can change sample-to-sample) +* 16 parallel samples per clock cycle (256-bit output bus) +* Maximum envelope length: 65536 samples per channel + +For complete documentation, see :doc:`/sg_v6`. If your board uses a +different generator core (multiplexed, interpolated, or the legacy v4), see +:doc:`/generators` for the full family and which one fits which experiment. + +Readout System +-------------- + +QICK ships several readout IP variants for the DDC/decimation stage -- +:doc:`/readout_v2` (PYNQ-register-configured, single tone), +:doc:`/readout_dynamic` (``axis_readout_v3``/``axis_dyn_readout_v1``, +tProc-configured per shot, single tone), and :doc:`/readout_pfb` +(``axis_pfb_readout_v2``/``v3``/``v4``, a fixed polyphase-filter-bank +channelizer that fans one ADC input out to several simultaneous demodulated +channels). Which one(s) a given board's standard firmware uses, and how many, +is a per-board decision -- see :ref:`std-firmware-per-board`. All variants +feed the same downstream block, **Average + Buffer** (:doc:`/avg_buffer`): + +**Readout Block** (architecture varies by variant -- see the pages above): + +* Digital down-conversion (DDC) +* FIR filtering +* Decimation + +**Average + Buffer Block:** + +* Raw sample storage +* Coherent averaging +* Triggered by a dedicated single-bit ``trig_N_o`` pin from the + tProcessor -- one per averaging buffer instance, *not* part of the same + channel-numbered AXI-Stream space as the readout's own configuration; see + :ref:`tproc-ports` + +For complete documentation, see :doc:`/readout_v2`, :doc:`/readout_dynamic`, +and :doc:`/readout_pfb` (the DDC/decimation stage, in its several variants) +and :doc:`/avg_buffer` (the averaged/raw buffer IP and its register map). + +The tProcessor v2 +----------------- + +The tProcessor (timing Processor) is a hard real-time co-processor inside the QICK FPGA. +It runs user-written programs that control waveform generation, data acquisition, and feedback with nanosecond precision. + +For **complete documentation**, see: + +* :doc:`/tprocv2_trm` - Full reference manual (architecture, instruction set, programming examples) +* :doc:`topics/asmv2_cheatsheet` - Quick reference for assembly programming + +**Quick links to tProcessor topics:** + +* :ref:`tproc-quick-ref` - Most common instructions and condition codes +* :ref:`tproc-registers` - Complete register bank reference +* :ref:`tproc-examples` - Copy-paste ready code examples +* :ref:`tproc-peripherals` - ARITH (multiply), DIV, LFSR + +.. _std-firmware-per-board: + +Standard ("_std") Firmware Per Board +------------------------------------- + +QICK does not use one universal channel layout. For each supported board, +the ``qick`` firmware repository ships a **standard reference design** +("_std", under ``firmware/Top//tpv2_std/``) that provisions a +different mix of generator and readout IP suited to that board's DAC/ADC tile +count and I/O capacity. A board's *other* firmware builds (e.g. the ZCU216 +"_demo" project) can provision yet another mix again. There is no fixed +"channel N is always generator type X" rule across boards -- what follows is +each board's own layout, traced directly from that board's block-design +source (``bd_2023-1.tcl``, on branch ``feature/114-integrate-hog-fusesoc``) +rather than assumed: + +.. list-table:: + :header-rows: 1 + :widths: 18 10 12 12 10 12 12 10 12 + + * - Board (``tpv2_std`` unless noted) + - :doc:`/sg_v6` + - :doc:`/sg_int4_v2` + - :doc:`/sg_mixmux8` + - :doc:`/sg_mux8` + - :doc:`/readout_dynamic` (dyn v1) + - :doc:`/readout_pfb` (v4) + - :doc:`/avg_buffer` + - :doc:`/mr_buffer_et` + * - ZCU111 (``firmware/Top/111``) + - 8 + - 0 + - 0 + - 0 + - 4 + - 0 + - 4 + - 1 + * - RFSoC4x2 (``firmware/Top/4x2``) + - 2 + - 0 + - 0 + - 0 + - 3 + - 0 + - 2 + - 1 + * - ZCU216 (``firmware/Top/216/tpv2_std``, flagship / QICKbox) + - 4 + - 11 + - 1 + - 0 + - 2 + - 1 + - 10 + - 1 + * - ZCU216 ``tpv2_demo`` (not "_std") + - 2 + - 2 + - 1 + - 1 + - 1 (plus 1 ``axis_readout_v2`` + 1 ``axis_readout_v3``) + - 0 (1 ``axis_pfb_readout_v3`` instead) + - 7 + - 1 + +Counts are per-board instance counts of each IP core, obtained by grepping +each board's ``bd_2023-1.tcl`` for its ``create_bd_cell`` lines -- not a +per-channel numbering scheme. See :ref:`tproc-zcu216-example` below for how +the ZCU216 ``tpv2_std`` numbers above translate into an actual tProc +channel/DAC/ADC map. + +.. note:: + If using the Xilinx XM500 daughter board (ZCU111), be aware of DAC/ADC + tile filters (a physical hardware property of that daughtercard, not of + the firmware's channel numbering): + + - DAC 229 CH0/CH1: **High-pass** (1 GHz) → output ≥ 1 GHz + - DAC 229 CH2/CH3: **Low-pass** (1 GHz) → output ≤ 1 GHz + - ADC 224 CH0/CH1: **Low-pass** (1 GHz) → input ≤ 1 GHz + - DAC 228 channels: **No filters** + + This note was not re-verified against the ZCU111 ``tpv2_std`` block + design in this pass (only the ZCU216 design was traced in detail); treat + the DAC/ADC tile numbers as Xilinx's own physical labels, independent of + whichever tProc channel happens to feed them. + +.. _tproc-ports: + +tProc Waveform Ports vs. Trigger Outputs +------------------------------------------- + +In tProc v2, two architecturally separate sets of ``qick_processor`` ports +are involved in driving generators/readouts and firing triggers -- unlike +tProc v1, where a single AXIS-channel numbering space carried both (this +page previously described tProc v2 hardware using that older model; the +distinction below is the correction): + +* **Waveform/config ports** (``m0_axis``..``mN_axis``, driven by + ``WPORT_WR``/:meth:`.QickProgram.pulse`) are full AXI-Stream ports that + carry generator pulse commands and dynamic-readout per-shot configuration + words. How many exist is a synthesis parameter of ``qick_processor`` + (``CONFIG.OUT_WPORT_QTY``) -- **16** on ZCU216 ``tpv2_std``, matching its + 16 total DAC channels/generator instances (4 SG-v6 + 1 SG-mixmux8 + 11 + SG-int4-v2, per the table above). +* **Trigger outputs** (``trig_0_o``..``trig_N_o``) are independent + **single-bit** pins, each wired with a plain ``connect_bd_net`` (not an + AXI-Stream ``connect_bd_intf_net``) directly to one PMOD bit or one IP + block's ``trigger`` input. How many exist is a separate synthesis + parameter (``CONFIG.OUT_TRIG_QTY``) -- **20** on ZCU216 ``tpv2_std``. They + are not part of the same numbering space as the waveform ports, and (also + unlike tProc v1) they are not bits packed inside a generator channel's + data word either. + +Both counts were read directly off ``qick_processor_0``'s ``CONFIG.*`` +properties in the ZCU216 ``tpv2_std`` ``bd_2023-1.tcl`` this session; they +are synthesis-time parameters, so other boards' firmware can and do +instantiate different totals (verify per board rather than assuming these +numbers). + +**Full ``trig_N_o`` mapping, ZCU216 ``tpv2_std`` (verified via +``connect_bd_net`` on ``qick_processor_0/trig_*_o``):** + +.. list-table:: + :header-rows: 1 + :widths: 20 40 + + * - Trigger pin(s) + - Drives + * - ``trig_0_o`` .. ``trig_7_o`` + - ``PMOD0_0_LS`` .. ``PMOD0_7_LS`` (all 8 PMOD0 bits) + * - ``trig_8_o`` + - ``mr_buffer_et_0/trigger`` (see :doc:`/mr_buffer_et`) + * - ``trig_9_o`` + - ``ddr4/trigger`` (DDR4 streaming capture) + * - ``trig_10_o`` .. ``trig_19_o`` + - ``axis_avg_buffer_0/trigger`` .. ``axis_avg_buffer_9/trigger`` -- + one dedicated trigger bit per averaging buffer instance + +This replaces the old, incomplete claim that readout triggers were "bit 14" +and "bit 15" of a channel-0 data word -- on ZCU216 ``tpv2_std`` there are 20 +independent trigger pins, only 8 of which are PMOD, and the remaining 12 +individually fire the board's 10 avg_buffers, its one ``mr_buffer_et``, and +its DDR4 capture path. A board with a different avg_buffer count (see +:ref:`std-firmware-per-board`) will have a different ``OUT_TRIG_QTY`` and a +correspondingly different mapping -- always confirm against that board's own +``bd_*.tcl`` (or, from Python, treat the driver-level trigger/arm calls as +the source of truth rather than the raw pin numbers). + +There is also a third, separate set of ports: **feedback inputs** +(``s0_axis``..``s9_axis`` on ``qick_processor_0``, ``CONFIG.IN_PORT_QTY=10`` +on ZCU216 ``tpv2_std``), each individually wired (via a per-channel clock +converter) to one averaging buffer's ``m2_axis`` live-feedback output -- +i.e. one real-time feedback input per avg_buffer, again not "2 input +channels" as this page previously claimed. + +.. _tproc-zcu216-example: + +Worked Example: ZCU216 ``tpv2_std`` +-------------------------------------- + +The ZCU216 ``tpv2_std`` design is traced here in full (it is the flagship +board and what ships in the QICKbox). All of the following was read from +``firmware/Top/216/tpv2_std/bd_2023-1.tcl`` (branch +``feature/114-integrate-hog-fusesoc``) in this session -- generator counts +match :ref:`std-firmware-per-board` above. + +**DAC side -- tProc waveform port to DAC channel:** + +The RFDC (``usp_rf_data_converter_0``) has 4 DAC tiles, 4 channels each +(``s00``..``s33``, 16 channels total). ``qick_processor_0``'s core clock +(``t_clk_i``) is tied to DAC tile 2's sample clock; SG-int4-v2 and +SG-mixmux8 (tiles 1-3) run on that same clock, so their tProc ports connect +straight through. DAC tile 0 (the 4 SG-v6 channels) runs on its own, +independent sample clock, so those 4 ports cross through a +clock-domain-crossing block (``axis_cdcsync_v1_0``, RTL parameter ``N=4``) +first. + +.. list-table:: + :header-rows: 1 + :widths: 12 18 20 20 15 + + * - tProc port + - CDC/demux stage + - Generator instance + - Generator type + - DAC tile:ch + * - ``m0_axis`` + - ``axis_cdcsync_v1_0`` (4-ch CDC, core clk → DAC-tile-0 clk) + - ``axis_signal_gen_v6_0`` + - SG-v6 + - tile 0 : 0 + * - ``m1_axis`` + - ``axis_cdcsync_v1_0`` + - ``axis_signal_gen_v6_1`` + - SG-v6 + - tile 0 : 1 + * - ``m2_axis`` + - ``axis_cdcsync_v1_0`` + - ``axis_signal_gen_v6_2`` + - SG-v6 + - tile 0 : 2 + * - ``m3_axis`` + - ``axis_cdcsync_v1_0`` + - ``axis_signal_gen_v6_3`` + - SG-v6 + - tile 0 : 3 + * - ``m4_axis`` + - ``axis_tmux_v1_0`` (address-tagged 3-way demux; direct to + generator, or via ``axis_cdcsync_v1_2`` for the other two) + - ``axis_sg_mixmux8_v1_0`` + - SG-mixmux8 + - tile 1 : 0 + * - ``m5_axis`` + - direct (same clock domain as tProc core) + - ``axis_sg_int4_v2_0`` + - SG-int4-v2 + - tile 1 : 1 + * - ``m6_axis`` + - direct + - ``axis_sg_int4_v2_1`` + - SG-int4-v2 + - tile 1 : 2 + * - ``m7_axis`` + - direct + - ``axis_sg_int4_v2_2`` + - SG-int4-v2 + - tile 1 : 3 + * - ``m8_axis`` + - direct + - ``axis_sg_int4_v2_3`` + - SG-int4-v2 + - tile 2 : 0 + * - ``m9_axis`` + - direct + - ``axis_sg_int4_v2_4`` + - SG-int4-v2 + - tile 2 : 1 + * - ``m10_axis`` + - direct + - ``axis_sg_int4_v2_5`` + - SG-int4-v2 + - tile 2 : 2 + * - ``m11_axis`` + - direct + - ``axis_sg_int4_v2_6`` + - SG-int4-v2 + - tile 2 : 3 + * - ``m12_axis`` + - direct + - ``axis_sg_int4_v2_7`` + - SG-int4-v2 + - tile 3 : 0 + * - ``m13_axis`` + - direct + - ``axis_sg_int4_v2_8`` + - SG-int4-v2 + - tile 3 : 1 + * - ``m14_axis`` + - direct + - ``axis_sg_int4_v2_9`` + - SG-int4-v2 + - tile 3 : 2 + * - ``m15_axis`` + - direct + - ``axis_sg_int4_v2_10`` + - SG-int4-v2 + - tile 3 : 3 + +Every ``qick_processor_0/mN_axis`` port passes through a ``sg_translator`` +instance before reaching its generator (18 ``sg_translator`` instances exist +in total: 16 feed the generators above, ``sg_translator_16``/``_17`` feed the +two dynamic readouts' config ports instead -- see below). Register slices +(``axis_register_slice_0``-``_7``) also sit inline on the SG-v6 path, but +these stay on one clock (they don't add a second CDC hop) -- they're +ordinary pipeline stages for timing closure, confirmed by both sides sharing +the same clock net in the .tcl. + +``m4_axis`` is the one port that isn't a clean 1-generator mapping: RTL for +``axis_tmux_v1`` (``firmware/ip/axis_tmux_v1/src/tmux.sv``) shows it demuxes +one AXI-Stream input to one of *N* outputs by an address tag carried in the +data word itself (the top 8 bits), not a fixed per-port assignment. On this +board (``CONFIG.N=3``), that lets tProc channel 4 carry pulse commands for +the SG-mixmux8 generator *and* per-shot config words for both dynamic +readouts, distinguished by that tag -- one of the demuxed outputs goes +straight to ``sg_translator_4`` (mixmux8, same clock domain), and the other +two cross into the ADC-tile-2 clock domain via a second CDC block, +``axis_cdcsync_v1_2`` (``N=2``), before reaching ``sg_translator_16``/``_17`` +and then ``axis_dyn_readout_v1_0``/``_1``'s ``s0_axis`` config ports. + +**On the CDC blocks' purpose:** ``axis_cdcsync_v1`` (RTL: +``firmware/ip/axis_cdcsync_v1/src/cdcsync.sv``) exposes independent +input-side and output-side clock/reset pairs for up to ``N`` parallel +same-width streams -- it is a clock-domain-crossing bridge, confirmed by +tracing each instance's ``aclk`` nets in this board's .tcl (input side tied +to the tProc core clock, output side tied to the destination tile's own +clock). It is **not** part of the ``xcom`` multi-board synchronization +mechanism (:doc:`topics/xcom`) despite the similar name -- that is a wholly +separate IP block with its own network/serial interface. Both CDC instances +on this board exist purely because DAC tile 0 and the ADC-tile-2-clocked +readout logic run on clocks independent of the tProc's own core clock, not +for any cross-board purpose. + +**ADC side -- readout instances:** + +* ``axis_dyn_readout_v1_0`` -- ADC input from tile 2, channel 0 + (``usp_rf_data_converter_0/m20_axis``). +* ``axis_pfb_readout_v4_0`` -- ADC input from tile 2, channel 1 + (``m21_axis``); channelizes into 8 outputs, ``m0_axis``..``m7_axis``. +* ``axis_dyn_readout_v1_1`` -- ADC input from tile 2, channel 2 + (``m22_axis``). + +Each dynamic readout's decimated output (``m1_axis``) and each of the PFB +readout's 8 channelized outputs feed their own ``axis_broadcaster``, which +fans out to (a) one dedicated ``axis_avg_buffer`` (1:1 -- 10 total: 2 for the +dynamic readouts + 8 for the PFB readout's 8 channels) and (b) a shared +10-input AXI-Stream switch (``axis_switch_ddr``) feeding the single DDR4 +capture path, letting software pick which one of the 10 channels streams to +DDR4. Separately, the two dynamic readouts' *undecimated* outputs +(``m0_axis``) feed a 2-input switch (``axis_switch_mr``) into the single +shared ``mr_buffer_et_0`` instance. This matches, and was cross-checked +against, the independently-traced fan-out in :doc:`/readout_pfb`'s +":ref:`readout-pfb-zcu216`" section. + +Checking Your Own Board's Configuration +------------------------------------------ + +Every table on this page describes one specific board's firmware build, +traced from that build's source. Your board may be a different one, or the +same board with a different firmware build -- do not assume generator +counts, readout counts, or channel/trigger mappings from this page apply to +your setup. Instead, read them from the running system: + +* ``soc.gens`` -- list of generator drivers, in board-config order (index + is *not* guaranteed to equal the tProc waveform-port number -- see + :ref:`tproc-zcu216-example` for why that mapping can be non-trivial). +* ``soc.readouts`` -- list of readout drivers (mix of + :doc:`/readout_v2`/:doc:`/readout_dynamic`/:doc:`/readout_pfb` types, + board-dependent). +* ``soc.avg_bufs`` -- list of :doc:`/avg_buffer` drivers. +* ``print(soccfg)`` -- full human-readable dump of the board's configuration, + including per-channel generator/readout types and every buffer's + ``avg_maxlen``/``buf_maxlen``. + +Timing +------ + +- **FPGA clock:** 384 MHz → period = 2.6 ns +- **DAC speed:** 384 × 16 = 6144 MHz → resolution ~163 ps +- **ADC speed:** 384 × 8 = 3072 MHz, decimated by 8 → resolution ~2.6 ns +- **Minimum DAC pulse length:** 16 samples (shorter pulses can be zero-padded) + +Firmware Parameters +------------------- + +.. note:: + This table previously carried tProc-**v1**-era figures (8k-instruction + program memory, 256-sample stack, 16-bit gain) copied into this page + unchanged. tProc v2's real numbers, confirmed against + :doc:`/tprocv1` and :doc:`/tprocv2_trm` in this session, are quite + different -- notably the **stack is 8 entries deep, not 256**, and + program/data memory sizes are synthesis parameters + (``PMEM_AW``/``DMEM_AW``), not a fixed "8k"/"4096". As with everything + else on this page, treat board-specific sizes as something to read from + ``soccfg`` (or ``soc.tproc.cfg``), not to assume. + +.. list-table:: + :header-rows: 1 + + * - Parameter + - Value + * - Pulse memory length (per SG-v6) + - 65536 samples ×2 (I/Q) = 128k total (``N=16`` default -- see + :doc:`/sg_v6`) + * - Decimated ADC buffer + - Board-dependent, ``2**N_BUF`` samples per component (I,Q) -- see + :doc:`/avg_buffer` + * - Accumulated ADC buffer + - Board-dependent, ``2**N_AVG`` samples per component (I,Q) -- see + :doc:`/avg_buffer` + * - tProc v2 program/data memory + - Synthesis parameters (``PMEM_AW``/``DMEM_AW``), board-dependent -- + see :doc:`/tprocv2_trm` + * - tProc v2 stack size + - **8** entries (fixed, not a synthesis parameter) -- see + :doc:`/tprocv2_trm` + * - Phase conversion + - :math:`\Delta \phi = 2\pi/2^{32}` or :math:`360/2^{32}` degrees + * - Gain range (tProc v2 / ``w_gain``) + - 32-bit signed -- verified against RTL (``qcore_reg_bank.sv``) and + ``asm_v2.py``'s ``Waveform.compile()`` in :doc:`/tprocv2_trm` + +Related Documentation +--------------------- + +* :doc:`/tprocv2_trm` - Complete tProcessor v2 reference manual +* :doc:`/generators` - Full generator-core family (SG-v6, SG-int4-v2, SG-mixmux8, SG-mux8) +* :doc:`/sg_v6` - Signal Generator v6 documentation +* :doc:`/readout` - Readout system overview +* :doc:`/readout_dynamic` - tProc-configured single-tone readouts (axis_readout_v3 / axis_dyn_readout_v1) +* :doc:`/readout_pfb` - Polyphase-filter-bank channelized readouts (axis_pfb_readout_v2/v3/v4) +* :doc:`/avg_buffer` - Averaged/raw buffer IP downstream of every readout variant +* :doc:`/mr_buffer_et` - Multi-rate buffer (DDR4/streaming) shared readout path +* :doc:`topics/asmv2_cheatsheet` - tProc v2 assembly quick reference +* :doc:`topics/tutorials` - tProc v2 tutorial examples +* `Signal Generator v6 source `_ diff --git a/docs/source/generators.rst b/docs/source/generators.rst new file mode 100644 index 000000000..dd1456181 --- /dev/null +++ b/docs/source/generators.rst @@ -0,0 +1,106 @@ +Signal Generators - QICK Firmware +================================== + +.. contents:: + :local: + :depth: 2 + +Overview +-------- + +QICK ships several signal-generator IP cores. They all connect to the +tProcessor the same way (one AXI-Stream waveform port per channel, driven +by ``WPORT_WR``/:meth:`.QickProgram.pulse`) and the same way to a DAC, but +they trade off differently between **flexibility** (arbitrary pulse shapes) +and **simultaneity** (how many tones at once). Picking the right one for a +channel is a hardware/firmware decision (which core is instantiated on that +DAC channel in your board's bitstream) -- as a user you mostly just need to +know which kind of channel you have and how to talk to it, both covered +below. + +.. list-table:: Generator family at a glance + :header-rows: 1 + :widths: 22 15 15 48 + + * - Core + - Tones + - Envelope + - Typical use + * - :doc:`/sg_v6` + - 1 (arbitrary shape) + - Yes, full rate + - The default choice for shaped pulses (Gaussian, DRAG, flat-top) -- + qubit drive, readout drive. + * - :doc:`/sg_int4_v2` + - 1 (arbitrary shape) + - Yes, 4x-interpolated + - Same use case as SG-v6 on boards/channels where this lighter-weight + core is instantiated instead; has a DAC-side mixer (``HAS_MIXER``). + * - :doc:`/sg_v4` + - 1 (arbitrary shape) + - Yes, full rate + - Legacy predecessor to SG-v6; not used in any board design currently + in this repository. Documented for driver/backward-compatibility + reference, not for new designs. + * - :doc:`/sg_mux8` + - up to 8 (fixed CW) + - No + - Playing several simultaneous fixed tones from one channel -- e.g. a + frequency comb, or driving several resonators/qubits at once without + one DAC channel per tone. + * - :doc:`/sg_mixmux8` + - up to 8 (fixed CW) + - No + - Same as SG-Mux8, plus a shared DAC-side mixer so the whole comb can be + placed anywhere (including outside the first Nyquist zone) via one + ``mixer_freq``. + +Arbitrary-envelope vs. multiplexed: which do I need? +----------------------------------------------------- + +**Use an arbitrary-envelope generator** (SG-v6, SG-int4-v2, or the legacy +SG-v4) when you need to *shape* a pulse -- a Gaussian, a DRAG pulse, a +flat-top pulse with rounded edges, or any other waveform you can compute in +Python. These cores have envelope memory (BRAM) you upload I/Q samples into +with :meth:`.QickProgram.add_envelope`, and play back with an ``arb`` or +``flat_top`` pulse style. Only one tone plays at a time per channel. + +**Use a multiplexed generator** (SG-Mux8 or SG-MixMux8) when you need +*several simultaneous CW tones* from one DAC channel and don't need to +shape each tone's envelope -- only its amplitude, phase, and which subset +of tones is on for how long. This is the common case for a frequency comb +or for driving multiple fixed resonances (e.g. several readout resonators) +through a single physical channel. Pick SG-MixMux8 over plain SG-Mux8 if +you need the comb somewhere the DAC's un-mixed first Nyquist zone can't +reach on its own. + +If you need *both* -- multiple simultaneous tones *and* per-tone arbitrary +shaping -- no single QICK generator core does that; you need one +arbitrary-envelope channel per shaped tone. + +Common Python workflow +----------------------- + +Every generator in this family is configured the same way, regardless of +which core is behind a given channel: declare it once with +:meth:`.QickProgram.declare_gen`, define named pulses with +:meth:`.QickProgram.add_pulse` (and :meth:`.QickProgram.add_envelope` first, +if it needs a shape), then play them with :meth:`.QickProgram.pulse`. See +:doc:`/sg_v6`'s "Python Usage" section for worked examples (single pulse, +shaped pulse, multiple queued pulses), and :doc:`/sg_mixmux8`'s Python +section for the multiplexed-generator variant (``mux_freqs``/``mux_gains`` +instead of one ``freq``/``gain`` per pulse). + +Related Documentation +---------------------- + +* :doc:`/sg_v6` - the flagship arbitrary-envelope generator (start here) +* :doc:`/sg_int4_v2`, :doc:`/sg_v4` - other single-tone arbitrary generators +* :doc:`/sg_mux8`, :doc:`/sg_mixmux8` - multiplexed (multi-tone) generators +* :doc:`/firmware` - which generator core is on which channel, on the + reference board +* :doc:`topics/gen_config` - shared pulse configuration options + (``outsel``/``mode``/``stdysel``) +* :doc:`topics/freq_matching` - keeping generator and readout frequencies + in sync +* :doc:`/readout` - the readout-side counterpart to this page diff --git a/docs/images/papers/QICKpapers_count_Jan26.png b/docs/source/images/papers/QICKpapers_count_Jan26.png similarity index 100% rename from docs/images/papers/QICKpapers_count_Jan26.png rename to docs/source/images/papers/QICKpapers_count_Jan26.png diff --git a/docs/images/papers/QICKpapers_count_May26.png b/docs/source/images/papers/QICKpapers_count_May26.png similarity index 100% rename from docs/images/papers/QICKpapers_count_May26.png rename to docs/source/images/papers/QICKpapers_count_May26.png diff --git a/docs/images/papers/QICKpapers_qubit_types_Jan26.png b/docs/source/images/papers/QICKpapers_qubit_types_Jan26.png similarity index 100% rename from docs/images/papers/QICKpapers_qubit_types_Jan26.png rename to docs/source/images/papers/QICKpapers_qubit_types_Jan26.png diff --git a/docs/images/papers/QICKpapers_qubit_types_May26.png b/docs/source/images/papers/QICKpapers_qubit_types_May26.png similarity index 100% rename from docs/images/papers/QICKpapers_qubit_types_May26.png rename to docs/source/images/papers/QICKpapers_qubit_types_May26.png diff --git a/docs/images/papers/QICKpapers_qubit_types_pie_May26.png b/docs/source/images/papers/QICKpapers_qubit_types_pie_May26.png similarity index 100% rename from docs/images/papers/QICKpapers_qubit_types_pie_May26.png rename to docs/source/images/papers/QICKpapers_qubit_types_pie_May26.png diff --git a/docs/images/papers/QICKpapers_scaling_Jan26_final.png b/docs/source/images/papers/QICKpapers_scaling_Jan26_final.png similarity index 100% rename from docs/images/papers/QICKpapers_scaling_Jan26_final.png rename to docs/source/images/papers/QICKpapers_scaling_Jan26_final.png diff --git a/docs/images/papers/QICKpapers_scaling_May26.png b/docs/source/images/papers/QICKpapers_scaling_May26.png similarity index 100% rename from docs/images/papers/QICKpapers_scaling_May26.png rename to docs/source/images/papers/QICKpapers_scaling_May26.png diff --git a/docs/images/papers/QICKpapers_scaling_pie_May26.png b/docs/source/images/papers/QICKpapers_scaling_pie_May26.png similarity index 100% rename from docs/images/papers/QICKpapers_scaling_pie_May26.png rename to docs/source/images/papers/QICKpapers_scaling_pie_May26.png diff --git a/docs/images/quick_start/Bootmodeswitch.png b/docs/source/images/quick_start/Bootmodeswitch.png similarity index 100% rename from docs/images/quick_start/Bootmodeswitch.png rename to docs/source/images/quick_start/Bootmodeswitch.png diff --git a/docs/images/quick_start/Eafterwrite.PNG b/docs/source/images/quick_start/Eafterwrite.PNG similarity index 100% rename from docs/images/quick_start/Eafterwrite.PNG rename to docs/source/images/quick_start/Eafterwrite.PNG diff --git a/docs/images/quick_start/boardpic_cartoon.PNG b/docs/source/images/quick_start/boardpic_cartoon.PNG similarity index 100% rename from docs/images/quick_start/boardpic_cartoon.PNG rename to docs/source/images/quick_start/boardpic_cartoon.PNG diff --git a/docs/images/quick_start/ciscorouter.PNG b/docs/source/images/quick_start/ciscorouter.PNG similarity index 100% rename from docs/images/quick_start/ciscorouter.PNG rename to docs/source/images/quick_start/ciscorouter.PNG diff --git a/docs/images/quick_start/correctpynqversion.PNG b/docs/source/images/quick_start/correctpynqversion.PNG similarity index 100% rename from docs/images/quick_start/correctpynqversion.PNG rename to docs/source/images/quick_start/correctpynqversion.PNG diff --git a/docs/images/quick_start/jupyternotebook1.PNG b/docs/source/images/quick_start/jupyternotebook1.PNG similarity index 100% rename from docs/images/quick_start/jupyternotebook1.PNG rename to docs/source/images/quick_start/jupyternotebook1.PNG diff --git a/docs/images/quick_start/jupyternotebook2.PNG b/docs/source/images/quick_start/jupyternotebook2.PNG similarity index 100% rename from docs/images/quick_start/jupyternotebook2.PNG rename to docs/source/images/quick_start/jupyternotebook2.PNG diff --git a/docs/images/quick_start/largeimagefile.PNG b/docs/source/images/quick_start/largeimagefile.PNG similarity index 100% rename from docs/images/quick_start/largeimagefile.PNG rename to docs/source/images/quick_start/largeimagefile.PNG diff --git a/docs/images/quick_start/port_forward.png b/docs/source/images/quick_start/port_forward.png similarity index 100% rename from docs/images/quick_start/port_forward.png rename to docs/source/images/quick_start/port_forward.png diff --git a/docs/images/quick_start/pscpfolderstructure.PNG b/docs/source/images/quick_start/pscpfolderstructure.PNG similarity index 100% rename from docs/images/quick_start/pscpfolderstructure.PNG rename to docs/source/images/quick_start/pscpfolderstructure.PNG diff --git a/docs/images/quick_start/pullingdataofftheboard.PNG b/docs/source/images/quick_start/pullingdataofftheboard.PNG similarity index 100% rename from docs/images/quick_start/pullingdataofftheboard.PNG rename to docs/source/images/quick_start/pullingdataofftheboard.PNG diff --git a/docs/images/quick_start/pushingdatatotheboard.PNG b/docs/source/images/quick_start/pushingdatatotheboard.PNG similarity index 100% rename from docs/images/quick_start/pushingdatatotheboard.PNG rename to docs/source/images/quick_start/pushingdatatotheboard.PNG diff --git a/docs/images/quick_start/putty1.PNG b/docs/source/images/quick_start/putty1.PNG similarity index 100% rename from docs/images/quick_start/putty1.PNG rename to docs/source/images/quick_start/putty1.PNG diff --git a/docs/images/quick_start/putty2.PNG b/docs/source/images/quick_start/putty2.PNG similarity index 100% rename from docs/images/quick_start/putty2.PNG rename to docs/source/images/quick_start/putty2.PNG diff --git a/docs/images/quick_start/putty3.PNG b/docs/source/images/quick_start/putty3.PNG similarity index 100% rename from docs/images/quick_start/putty3.PNG rename to docs/source/images/quick_start/putty3.PNG diff --git a/docs/images/quick_start/pynqstartup.PNG b/docs/source/images/quick_start/pynqstartup.PNG similarity index 100% rename from docs/images/quick_start/pynqstartup.PNG rename to docs/source/images/quick_start/pynqstartup.PNG diff --git a/docs/images/quick_start/pynqversion.PNG b/docs/source/images/quick_start/pynqversion.PNG similarity index 100% rename from docs/images/quick_start/pynqversion.PNG rename to docs/source/images/quick_start/pynqversion.PNG diff --git a/docs/images/quick_start/static_ip.png b/docs/source/images/quick_start/static_ip.png similarity index 100% rename from docs/images/quick_start/static_ip.png rename to docs/source/images/quick_start/static_ip.png diff --git a/docs/images/quick_start/writetoEdrive.PNG b/docs/source/images/quick_start/writetoEdrive.PNG similarity index 100% rename from docs/images/quick_start/writetoEdrive.PNG rename to docs/source/images/quick_start/writetoEdrive.PNG diff --git a/docs/source/images/topics/fig1_xcom_block_diag.png b/docs/source/images/topics/fig1_xcom_block_diag.png new file mode 100644 index 0000000000000000000000000000000000000000..be554705e388243a4d11dcca3ddf382a21f50ddc GIT binary patch literal 68682 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

W-ZWKcp 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

@PT2QVGMW(J*N3qIo-5dD;xGwP7>gY){(T{{b) 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 literal 0 HcmV?d00001 diff --git a/docs/source/images/topics/fig3_fanout_box.png b/docs/source/images/topics/fig3_fanout_box.png new file mode 100644 index 0000000000000000000000000000000000000000..135ea468dd11846f314f3d97d405eb12f78d453b GIT binary patch literal 498340 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

GSglV*obC5L-2Ednt9rR|BC^qkOfkA3T@ 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%0A7cliYia-BID+NiRJWrKYj@)V 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

L>8f2O=sgkzz*l3qF4SF2QZH}jl3B(&@mRy5X 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

    (mbwL|q|Es;pr&_e?_7H( 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%0Db8>tYMrdTU5j3) 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

      RIYlmBnGY22wjxMxi@tWXZX6a}4Z6aL~YYh&x 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

      m(vk` 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

      sIGqg4o4G*rk;92@Fxx3bY#;m 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 z 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 z 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�D#-s<>xgM;?v)oPb zxoa`fb(I)Jz>(uk$=idM2K@2q6$gIgyggCBAd*vO_U}R)4?e*J*h|rQ`riQNWoOvr zL>idm3gTiuM0&!r7S=(jL^Z*XWdTZ&OSFLMv z{d8VmT6cWsBkuz8FauzRqX#G!<1Gdl&*ZE22-31hq-|wfc`QnoT5ALL!w3nk$kM%K z;IGTrllt4eV9y`+!M)1*W&X0`9pJ5z(dZx3A3e%*Za~dy4#P8mAv9l3$>uRaAXPkJ z1}=RT$Kk>mN*P-~Y$R&5i`cEln$p(vmIhTzL8W1)GGg=PvHr zZFa=?GEn5m4|)ya_M@LgVBX4BP69+fz&0!aZ}VDhQI^lak%PsO{eJV_ak2>Wp0mO` z1lcY*+^+@J{Ua&NPj`!)wrF#HmS4XY$_Qvb$EvsAGC+T`kbmplK-GMvlI3@ehE43u zw(l*Y0PeR4++LgcCf~o82aO=jnqy;4EqdC^D1pd<4t9>(-+Wg$?V)GOmgQAo=W=)3tehGBa)b0@UsU~@D1P2VdIzl*^*!HY z?v)9V1d449E3-jI7|(uhztHH&RjqBRRbOD5^8OZ^YcULmSMZ0j!-)WZk`y2vZ~?BP z-o&mFM00KAYz$^KfIuGa5SlSk)^6!0ySp6u5-6bD0A#tW?=sTbZqo1@;+z$F^mP|e zwg9{Yn#ja55Hd9k3FE+W=sj!-QKy^M_u3f9|FWKsash={R9Hf zzB7suc8;z;wk|6F2gF4AefR+6WJaL)-{|$ZFW9;n2pLa3n~kh0?Xs(AFpXi9pxbDG zKZg^bY^I$X^dXmSByw#PWQO1;^zq8_Ht@>)03v>#SPb^m<^i7~2xLIy*da`E?3Q=p zs+=^|tA%qUP_v&s2Qg1yX8|HsAXQ#0O_zAkTY^iai0>a1kWz0n11n?`KY_$3WFT*5 z2KuF>j<^BLQ7BWtPR%DuU_FAQd+;h?D-cS}z6*Z|i_uv`KtXPlbZI^yX3G2hg)EQ# zJv?Di2N$UwAQ}(@^n)Mp&U*mRs$fH8k`)(HALv*F0D&U`79VCA1zsA%*+??hZbcy- z#2WOk7&TE`cKkwJ(Ps!+M zi-1X+0H^gFa6%RGecV_VLyh5gv0uJq^A^qyhglNu-AY}?Z}V`45`rS zP2K7JDsrYg0G~t*%v7!AQ5Z1<8=MIU==a-YS_bZ%fszFy4_ohet<_ZfZTBjYcEs)u zN~2-l`33@IH0An8$bcRvqohi3Ate@{aL)79*tyQpTs~k<^aVf?!R9XqK(TRZ$*uSV zph$5>$b}EPs~S8CY&xcLeYBpr3xmK;!wp5QDYu4GLO%NmPdwPoK;f6)z38QN^>1|v zAgb(3_RGTJvb2Q3g!X_u-2kD{SpbvNW)Ts+W07x7N zp;LhsjVOVYIWFH)=;oL5-SxyP;^YyeA2uIKU&Gjb0_z`}0{~12kgBx`1xbFN8#pl5 z?m9Pll$&pgFc>-dPEK=OF2p3ln_E6Xx(2eK~b;AiE#ieT@q{{v|;lipX z@bf?rQV4EbNa9ypiD6g&u>DA8IixY`O%M@qWwh{+>US^07HXG257Zhi4Fv&0zWAwrAWmtAM*g703rfHFCzemr@w^Rai~zR z{Z%VKWdolAFPQ*>WX~1remJndftbM2GeVn-Gntu5k#n?Ns} z9ax{^7Y0ElAP$kR*M}z7aHxwiEd(2QVd#%SRa9_Nz5%OtpwOe6PaKo!0bUbezevGL z89Va$fgCO@JzO})mrYf=o#oqxFxpr*Lh+Ak?UMv295aXGF=T?`!i$gm`sMrUeX=TU zUx&=uZfn+H$$^#~Amq!2k?pwyPdJcPU{Hu9g#TNmRGv2(CIn8H4H7M9ovzLj8RB%tWI%XWB985ejlYGf>>8)kQW$~afWAm zr`}BHz;R)aIlCgC9K}CL-E(pP`upN^Ym+la-Cq8-ApAc3{)`dy^yvTpp_fnl;^fQ! zOrI*9Y8g{Qp6_U4ld@)`8=A$NH=w=0P76oq$D3i_XRjP1X5y2{097-9N_ z{g>GGmMGRfb)1WCxGMY3;dk;hKt9Bhzqu-qw*ipuH%*~&h$XE5JJ~Yodg?>3Y1Y{r45gm-SObYZA? zt$=;%U+H$u^F^k)Pn&r9rTWRqY&$&!zWmP!3jZ4-#r;w=-KF^Br{>*?p;_R-nJCrxyIKL zgkAaMRhjr6L8skBPgA*q|I9y5q5@2q0F!63{?wM>@>A0_-Fif+q&w9uP zQeAFhdOPc~Xyl=;)&8C7AF4-eR}*DMD$$yRG?L>Tcr!)d*sBi`x>L-7TUHJCQ6dim z)mh;kbKV?2H!{pF1)Ak1nxJ=6!$_{Lo#5aW^z`a@`QMD7Q1gf9-25Wv+}e8AIuEo> ztXrI-4kBECaJ`3y4?fE8stgW&kDF!CFamje;xrdp)%y)C`GKwH2RL;`4BFkj07Xa((*D`a5 zl6TFwa6p?U_{wvKku$mPbpbrG_{pfHoEBImsC%766yG%-O*N!e%z_66FkL zkQ7G>rTMGwH2ccg-%xnp)W_E)Oo*q*Rq@Fa3f;bg4QFtdHm^&Fy`$_CJ` zuz3wg0^QR$h)YY7v4`5>uK`4-$)p$WldpB)xh`hw^{;w1f~r#K0Xk6s>L0+=$~oNx zVt)g2uA|adfR$3#7v$|!0tV)hwYfJItJr?EiE6`fuot)BIl#}*$ItK&;@r8;&QYAQ zu$?-sG({3?-JzaR4u>_5wV}K=FE1%Ra_VN9^^Z^&LdDk{8FB;cCE`Pmn48%hL)g`AyEv_bM9cUIN3UKLAIx5F80Cj?czStGjNl~IBOMVo z7V8t(8>flCDavzG_mwQ_$Z9{c!vF%W?BI@qiLZY0_uAJ4SUUHvgaVSu71d+P$=j=2 z?~B=-TV;K~!RyP7@X^9UG1PG!0IGfrHum8rb-8skV}v9C9Y4*DiT1I&di=%6&QzQQ z{Ig#@5nVZpE7GKj6hqc~1|oj{A?ADVaNl?`=y9KT0(>{u{-QydN@lW2scRh#yV| z@e}#+Atfr~(9k%yM?vIl8L1QH7;>hlVJoYI+SAK971ej({aI7R%wso!kH&uA2}a=m z-Frcb0=u(oZNd-FR!AbFr8b`mixme;rw%J6AQlV-hYBD*e0=Y@1tL1#)>!ZPd)>H^ zH~{`s1bmiXhCiYPG%nucMF3Y>*(5VNjJDGDU`LBG0=P)fUU*w?TQ_LHwl>xxoK`>h zRZdn|^yLQr@`r$1vHQxq)yXbgNCA#j7~_IvVi3quoe@EQWG||0LD3|3r%9Z=NnD-U zi10|}=L8_1Tl`E|{!+s6%=AYf9ad}+f9$LdzvUV&dpB+biQd@H6v_t*O{lg``DrG~ z=r8Mg*&%xyG?)7%_k90G^ZvXwTvS`ezn8O{w{s{}zBkbi4cu{&P_mM)fbh6$Q?xMK z+G&ZZRJ-vyGW1f*o8S_TR1kTg9==vs1@JZ?S^`XMFq)io67HQ{W4NnFX@2#kCSg`g zS-MRD!79&*3T$i`3kunqXs7{tn9|eJGd4S$;ZRE*jlpqVf&!%3(b6|(xVV21S5d(W zcHMhoWMq_Im|y!428-PTgMYNSfxIa&Z>_qs&}P+&{to&cDs>X%gYZ5=sB(4t%g=L5HPmIWyn-Hhyz{~p z1S!}hQZjsE?_^n`;a>-@EG;XIEl9X$yF5a$7zyLEHHJs_rt=@P!#u3HNX*JMn~0Ns zQIVUL@MLV>#Kd)HUf_n@QnG`?KrTJ$N^;OC!mkL#>AZDEn9h-qQ1$u<*V>#W#ZCSQ%*yHZM}EHf=(cqwv*-Z%b6Bd4OI{Lqw|nw*~MIcPOo zPXN*(kSs6fn6`#09UN}txGef37Q8QL$9BDrb5BL7VFASkHe zU6ASx8Yw$5e&=Xu z<4Sk>H4x6>c3mlqWft}L_fJMAPNU|qJNCzDl-Jm{OODYNZ_Y+ZS)9YhXDkR{0>)@E z+1XIGMb%am`jv<%V7YP_HwO_+_4%aWc|{(?x6tDG$YEid!k8S!Ovf6cSc~_X7XdGz zRW0Y3X^kTD{1tqXsfI zmd-63`;NB5iMXQ5YKE+N{Q5OL7}qTQHVc#acaORxb8%qz2x z1RxdL?NkB#Kd-~;BcsfJpL$UjKqtcSkamdh!Noun7Zq+>? zCTF1V=hZpiS6wlO`-g5IHj4ICc$K^jn3b0S|gsHrG2Mq6iK&7@L={g#Q(~)47F@hkWuyt*q)=okE{}z zJ=?~$TArMdM&$kk?O~;w^L&Dgf&$w_$k&*!#U?kS1fV-Wfh#|BL<55+`s9(^@e%MT ze7#NrYi*pF-!BtvAQiq#%&f3Ub&|rqfCIOZu$LXyHDZ>5HtT(I2`6Y;WA9t6yKzVHMAiUpE4}wGQ5_li+vRUjw=m$y&=N zo#uKf3^az$7L9yLPjN9Jo{dR&9FTqdU!^)H78tkJmmB!Go&CRE77y|jxPkWK4mBN} zuV4ciSz46KHcopw1TkA4A>GhxBW=(I_g9M~%1Ls@Hk^H!I#Y^Q2v8aiH|HCKd6+9w zs0Z!2M7_exS3yo_v6F+>2;zJap0%d|9p5{Y4t&ZmsX@#%Pjtd zjwFc%G@KRo;~OOvEojq>8aLFYe;0-?6gG_AUq-pFJLw*MdpG&QB)&>v$JiZNgGbrZ*Y5{4I5sUUjc9GJ^CsUfc6#~>Z1@zNE|>7~bC+;U=r4bFo_crpM~WDax3;Src!CQf!f;MRYa z7wHlUnu!_iG`gu-WJz~HQ`tkm)z<|6mrBIb>NaUJ<=C`mVzqlGy8VR~Oq^NC zgv+^e?!2>d4BI}03PIv`?=5|+3dx5HfjeodPOi% zCN^Bop_=m|R;l2ne788D!O~&u&DsbbAClH|o#l*zaM2aR*ET^HPalEZ@F=gQJ zY^VQSL)14n56O)Vkt>I!)c@NKr~dh+sZCq4TZ|Qzw+R;sV{VN_N&*{(=+nOBkhj{ zk?mtH^+obyCd5^D#n;D}3z>=axVg0jZV}!1_Q1*RVY5D&&_Vt?OiGgL2??|TxMG7& z0wRz9zWuQxDI$U+XR@M*_IuaH-;ZOo2m1Vd8&(hYrY`iAAa```H44nC3J>qBD7;km zpf*aK-g0d91-f=e9Bay+5z>VcImhmM`8tODGu7AcwY3+#)BP8MzR-Eq-AMj$GPL|> zOuE+Gv(h0+3et=0e5BeKOt+62W3`8TZ=e3+im^%CUUb@ZF>opXY6%*9+fb(b*WR+@~vCNXw~wb<;Zjr@;k@3ac>X{3JZmtD!v_X^eg z$F(S4_kW@T%*6LYTg;QcBUc}3Bn#p&&5BJYonxxG>em*U-C&uikeuKwtN z>osLQfJ1C7Yo4w4=#heQ2Cni0T<|Hd4KAgs@U}2CgvN6*~0a@NkEX=*!c9_ zTjt21Pq?E0x zMIP`4cSq-utfXX|YGxl>yP=^$UsR-%7-$j+#!}dihMtoqZD)u6r`IPs&8k#&zxgWC zRFUd)-JN^)g^hN9@-4vml`Sl=0+;|5SUPpZ#*asZr#ax%u#F!q|jy zXH*nS41L3Qm;UarS467~9X(h7^$(gGU2JKkN=BsFm!RoMu0J!& z)y>d8ozBqr|4Be@nEHSQXvD|(mn|^eeSnUE=0@74nUid{y2}>G3}#$XMp@qR^P#t! zGyTDAtg9yiY2@UeTMbR_Z%f8QyH2BNd|`g~HvGt`CJ3+UzMYW~+OyLty#1pJw#S@r z!@$qW&+nlDHJ{*Qw8w9ryVKui-V=y&rOTCA9|czt|9oJJnA90Jr5~Z6C9efmbP!z)d`+QZ97y-7)C2{ z`Lcf!Phw7qD5pE-@nPsW<7t0z4Sjd8qR7i?*fnWsYJStn0f{tF?T|4x-Zk(WEH)}b zzB#Ev<*PsYaUh^#GQXj=HvH(06S!{E`1Wl~z;UDOSw7Pu;9YCMiiQN(xh5&axxt>UbWp8xK*l{T|K(njo(b#J+{FEWhT8h~&6+vq zDS#gXtu((IhgtNQjDrE%r(gG?ReJtWZ8qu@O8#X=fB%@jM8K4HTe)?&md?G#wn=Mf zotN_0jnztj&|SWa0TG?&^~*Wvs4c8Yy}DhHBB$eWp7f6vnpl^5O=Ku|85c&QB>)P0 zXg6*?Ahl=zyy?*ib=IGWl0JTOw2v6Iw2O>0SS@h9?mdL`kq(mc=)=-`_6|0IBN-Wg z9p{V!$3Ol#pn0D>K_3kM4U`o$w9&eG&k!C`zos1Y?!A{g+fXzQ)%G>eXKpleFHssoZ}BZ zG8A1ekI4BB$ZbUoTHWc*_^x?*4Q8JpuTW?r! z{COnX^j)a>Dhy) z-^Z{1LFT9Dz!&E~CjHs7ZuI{RlW}^*&kKJL!09>grScEK>Fn8RJmWK+!Z7r$z)Mb6 zW5dT!Son$2*MPl~)${B2(kF{tyXI z&w(%1c>g~+9{*q4=z$hYv|B%^#l*L~R$)~&i<397x5lxht?dyTetfB0Gz#FGO%Xiv zJF~8}J@46(1T$24)N;%wl+F2>dq029?uCpNWwRG|eqSS$_lH>e`y^Pi^Rh!o(B|mM z)w9IBJOk|JJ~nxJ%E_xA?L~QBDPUp!K5yMLZQV3)P2Ff1*lHR?&Y^_W+3D%&t6=>2 z^(R@`!0^aSKEweH+wHGQ(vTeU--{zLm`P+eNqJKv!q|=AZ4ph})*_NVJ|-%&+xAno zWxXRk@k0xSIFaMQ!MpZ4m;|vewdyI2mXrkRYVrSX8t@YWVlB%lsHV${2N@2R+N4s_ zZVmJG;@}MB>iQI>E0cTG#U2T~*FVfRAmrBZymN;fQTQJ=8HWCQvNQ8tDI2Z6SmynQ zYixOEOqp(XJwx2sng>heX>e(~BA17Ol6e+eZ81Ln+@unY*HED>(UD!RoI)r` zf}|>4&>$A-GX2lb=}T&tE`5r>6(-3RCTZ&~0Dk--itv!pmhisu`Ey`bS&`$`N=EIJ zw(^_TExty<3PsNa_x7miD4)u>Rst%Qe=eUe6iUe2)7La@`5jQ#vMmjuE?y2LU;3i~ z5=>5FAcMW9rr~9b29=j#cTzeL5(|VT`#I5q~rlgi1zHNB-_8pZ~<3AWJON-!cKr$G;2BWVPZjmj~knoVJ~pCoMcY0F9;mCE#vYo&8d5 zwO_g~I@)de&lMTXZ5ynbAA7n+(yRD)qcK;;Oi*S3Ac}e5kZ~spW>q9!hdYW-CQ9`# zdC@&nfmiA_>^~DUNWraId(W1kN>$XXV;fE{|0OUbH(g@5KP%`i7?V`w_*X&(d{mq{zWvo^RKrg{7(TXw$0%b?P3f;KW*yl00agdd@EP*! zo51idiErcYz7u@Xh(-LstCw2ODi3r^YD(%e9fuOJt5*X7XI{r7dFCMMp^=Y@r8tFIHi{tD{&4NLUhcPujdC=iXY0T zhr6xWnvA74zz&{|I>KFYhnHOkwKf)d9rvP;Q#&WZ_vy>QmvQu)%rU|$n+s{FndvOf zD{u4K`vm*d(?CB&>D`Nup9Ais?!noJB+ssA8GE~08T&s4SbO@3egSrNyDQboHoGSM z7VF6njXwv4F^M~_`tb@;o$Nh{HaakDgtxd{;Dr&zO>6YYG{i1K8tj)wy~!_q)D?YV z)&Mo>;FJM$lQcKL=(7F8{e7Faw{M>$5^NmDWEc=*<>w_W)^$NqBcmipHI|jkB_5h8 zTLlHKgU8?%e62~nD5?xIjn>M!J2kpo&s8>C$o(3ptqIw%(Mr=u+-*}*66T4>u47>K zCbwYymh`L!Ol-F##S~RkJ#WNL-dwokU!$v-mnPWSh8x(gkeVH2u zEv}cHO0r_&6AlS(%0I#%9^itfDr3+}QfE@jKN8IGq!w@Sg{&B;;wA<5)ZFA)<=F}6 z$;f!$D!w?ZSTyF8rHOsxT9^aV*W0&4b6&inXb(@(SuKy7Uag`pYM$P4@!39%^D{(v z;*hArMwg3>*1ZWXQW%!4PiRh)@TDJ)sLBU?Nlh(R?F|exG%) ziWWQQPK{5e508f({STegi1u- zBgwXz&!j{PmpVssW_JVDMz`w6^tYbeh?`_}nUeEqC5{>MNHI~7?S7iJ>~58Bx~jX( zl?zlvOi{Av+wsO5v?M_;ph8;0SJMFO01&MP$FQjy8#+^1EO$|*o zQ*YdY1MPZ*E{Je(QC?m>a|CfvwQcVx^j=6hJlR4oGG(f#u;Tk_8kmoWi39lR&;8=s zC%n70*!Nw^fg;S!X55kFg}2xd$-C}Yai6DcL(oCq#Ux|h%BsKwF?;_@EyZ1ZKvAK5 zu*z>PhsgPku?m$U=RHv}dRpprgQFi6PFoXjf@K)IS9g^4|F79)ldAM_* zBaAlNhVI>epnv81)N9RlU5HUQCW6B*;l>>eQc_s5?O>)g1 z`jVY~(zN7^u9NqQx?(-16Lf57*}R2rx2ganmL@{(z9dd@xa)JUl0Qm0<~!iCv#pL_MPP5D+;?mem7jOJ>M0saPG!_RIg@lg6!<#;pIHg zH|q}Sj*sa_bH;~5`7Bc-RrWsto_$S(Kq8weYs>))~MdM`TBYGj#$jMl#q(xp)$6PtoBiY6fDb3QLJ90+EFqz;6BoPVzzWHgh^-0FMdX;6eiC0#I!qJnsXsi!>?;}4nA$=9p;9eolN`4hASj$CFx zq$KR~SIXyfF+`U2c9(v*pf7%1JW}+dcU0iEv?Jn!lNmo^Yb9lt#FGe*OJ+dAC32-T zLrpnXxgz*q7OEdk(Ju3Ju}0ocnXNo^GP}uwJ+FA{eSL_gEx9m4SeHkvSQ%)VKPu1h z^tr5ij5+Tcu(GmUbY2}DE}SnavxP*ozVxf~0d<;}?cZ;66zlmNA(Hr05_7xgH+GES znf#-6Q7g{lf4vjlM{1)wUakL^qMARil+~X$lSskZ*PjM@Q207&572z_t-689m}Qq$ zZ>7?usl8Qx)!Q30177J`@v^Fa*9>?=3=sPUPZhp=>h8K36`sCZ`vl0HO+Y9rtGNy2 zqM&Z7pzf6SrChyo@+pO-DmsFK)KrvDEgrq{TwkBsw)%c*EU8X;%k|iLR*;=0ZS_T7 z+LSBBt-0?p>e&-ecbK*S%|^G z{cSZnDwYQ=Jv{gGTo8`Dh(>ZyF(*yIADwZIhecJr5mkFW#mh_!j zk2)43q4-fu%$3U+^4iw<&$_y+){2LxyK=~dt*5I0B57>vJ6bY^WUojRQ-&Hf{^a#C zCSqxwj5<$I19YgjATHv?7)B`1rnlP?do29vsLLAde)ll)TBEB;AU;XfLFOS@-CN;3 z7y7i`RI~OHu}@qkoZWSw+q>&z+hjkoHueyM!FZ~hRp~f2dSCvjjIrUD&+{I~%K-Go z=w-;R_;*Z6il~$A5`%W1_eQ&-l6~>*ycd;C>z0W5S$_74fcZ3_QT1xLu3ZJnQy9rK z5u5XVN~GiN%c>wIlAtnJ)tJj#o!b&5kVem1o=0D78O*bRYaGSq$R_TZM46C0Pz3H2 zNVJVnPHd0LIzS%T0l_YoEs&|;U8|{L)vI%ma=$+&?HY@8+Ezwv`oVh2o9Pu*G^Dgo zx%QD(j*@l5>($L-%Rr+Uf4zX0VWC1x%M_IY79|ss}66=L(ELAOQFiMxW;r^|r z?8Y-5N*M}U-&=b26xCCl$Q+(r=Q%2-E1n^|mz1z)qX9h-DjgfDu6-8>KXZ;O;s3>I z(8v*CSAR`*JCbShni@xnRk*a%VmVR3jj)?PT{0BXOf}3uKb!n?u5!oYyz(3Cow_1@ zF*mQ$p*u`0kNL|E-6Jx?Q|_PXf^7ge;Qi*0IKT+`%&O}R7RYNM7p!{a6&KBR;905b zmU(gEat1GBj@HWH-v_%iZEv#n^v$dI;w7!v8nOBd4()^aupKBo)`;bz zGy>z$coMAqdu4Z$Rn`LW;b*noj+G|dYmNf16eSd*jY zH!tnEUngSHo15!|8h~4IREjc3c(XkR!V56bY1v-u&N%!jaBOy)dvsA(2Qtvq%zm+p z)=r5{Z~0gu@a-Fm{;s)zF2Oy(NttmUbOeijZUHd%U!^qp=SPM-^7B2xM>VVzR&NIx zCG1)`gD7jUjKRZown);iQnayh3xy@z+w5YURn@fhCfzALX)796y{;`Bg-+vxu+hxU&lCnffBtB~XAuDwuPa_3p32I8UPw)|G2by= z9?2I4qQic9f0{I3N=%$E%>$khw<)!5UkoDaUfLqc#`+*SsJ5^CS#8rXmq(4}T0FbD zY_kkZ^%=BRfkFgi6rkyxw5XamNFqXS-~mu#5EtAFTvu_I={eF<_X$}GS*W-kJhSiz zS&bMaKD&F%W)*AKY_mLGt(A*l)DL*M0o*$Id*f0j14Z(6feESUS^mA6G7?Yn!7O8a z*?|v9r7>S)-Y*-RFKf*Vn^mVt>kW2d)gv2CA_3Y<*7!$i!!$Yg$gMC|5&xH1O(H9C zG6Xd&4s!%o3b~z!^tOWyREqTSwsDA=?y{d$*R86<^p$B=YWc`V&Upd?XrR@RJ5|$b z_RgU%bCg(sq+zpCRGBb0Fkr?*ibas}p;2UOVf49PYeZTc`t^mt`;kw_VtlJ!jXYIM zx@T4%BW_mS={|MjKadvG7R)7IQ|~Kp>|B0FOS1=DkQ;l)M7=^KOd(UwO7?U60ZUIm zjUCbz1D~zM4TZ-rcRc5Qo!wd2MN+b?KR-VoKi5t~f0j$;w{3Qr87x>^((^`*>7N#u zc(;Ct4@JPniTvby!0w%yV(3?_w)#Q^LwRS6)fkume#iCr+TgGv5VdI1>VlbKx15R= z2K_W-)npOuq(-U63Nkt#g~TH%$=R1iITo)-67%$Zbn(f4@y+<&lZHK>`v-ICK&~^H z4#aVuWVB0r-pWb~bi0mv#PDYQ!gcE{PCTQ9>@~h+ht^H;&1O90T=xl*9}Nu#c>bt5 zu*}`I`qb5RE#%zB(paG+dTyReC>BtqS4Uim-un^t&#=0nU+Yl2&X=rrw2rqtkR4Ow z1S_=9(N!~l6+7t+!ydf^YyhQmrHjyD08e@4wvvQuxaPzJ3j>X~6rR07dZ%2By5Kw)g(scq-529wva|~m~)Q~U3{IX1wJ14y&<<*s6 zWpW+FVy=b_rbV^kbBKjqUz+=Q4K{CjM)a7Z)O}o}sQBEdkr<}x?NO~#X&xiJXu=j| zdh}hI#d>qjHp>Rc62o?*3H)%UEMHQdff&T7X^{e*TIvNwwceO5Az%~lgoL(F!%vlP zqXOc|5c~a(yR-cLIU}l3+pUY^Rw(;B2^Il~$*zPRx@QOw?`}IOehEs8kB*k)Z$9M) z);cSF3bgPXF|!Qi`1dpQ*rbz&>9QtT5xxOaMmlYdqQC$`)=J1MDOE)C(PH>6&s~YQ z1HC<-Bw$g3IWLl#&;hw3I#%g=#a8i3#f0z`i}MHJad8yac?Ak@!KGgzUrY*vYxeg` z{cs2fQ#S7Js(Vg(g~YXO?ydgFVD%c3Z`zb6Gd>itz+w#LUJ1usg^d*xM5G3%aR27^ zXmAL_vm2IIGWd~GhLI640Zy?iR}1tGY@>9;?e?ZgsDbQbTC|wRy$Vc7$u-Oh^v@If z`uZ@l*dL4NC!1F6jM=I+E?&ayvs*1`NNQL61CGiwdhD{SH$nvKN4 zT8p8qd>PUbqMb`u={GrrpJk~N!upg+)HM`k4qGh};w8(zRh&DNKV=+9D$2^0?^WJC20)CtkdR4H`b=duo! z_om*p==UXEUS%6AbNPNPw&NZda(wnQYh6bM$0!|Qei@cp zUf8un>B^Yiek)4v!Qi1sJF{wrDJ{IRX_k|Ok&;%{Hq30+5;p+P0E`-+-k^ha(G?m` zm&k4`?2A6z1_<8~VjTHE!cRJgFU@xj!%y{%D)O>sJ{q%QYE;+WajGD!rl@SA_FWZoOsDp83;paZ^5IMI!Rg|6F zKyh$=FW|)>;A3XuDjhZQ-c??x$~c-MM@*pecNih}gTO`%n!BeSB)5l7cB40Ng5?4x z&45L~(?=h9AfX}uOf9jdP8j2Rp6M#Cz)Zd(uysc1;fIW-&%U&Wf91>22w5I(m8xo* zx1E2{>5rMU8WEhBoGntbp08-<`db~Xgw~PBnjZ|>zRmM2+L(W@HoiIs2y?MJNdT`c z(i?boJ1r~#S*j={L$d#RzP!1}2O(dw)o$8%DZYL!tY1Nh=Q?1=47a||vXKm!4x|@e$w8-~tyFaHcPb}c zZW{*9?UeY`mZYtaihaU>c$ddHvr4 zu<$!!p;SAe_rR`+(Qc)xY>~sKT>LcZfhr~NE(dH{Z;>!OtT@0Ir=Tf zIs<*7wBp4ZI>PjfOg1pYS^14c?463VYN^0IP8d*+56mTh(d#xbL`PF|+E+08o=o-9}txld+3~@k@NVIc7aOZ zr^q7*QEVN_la@wfui5kN8~1bNY3<4zKgn-rUT?Z`O=O*H?_#@=SMdk@s6ITon|szr z6R-_?Uh4D*GVplo8r?|Wtb1w(YgCT&4KQ{}AI4{z&NL$nA0mJLXRAIWQwq$;Dazq9 zp}$g8Rxz|aUn3t7c)__n-xc8;31rNvOPIjRYt`V6Z~qL!j-eg0`!&SrA=mM$0&fAA z`cRC`=S1oLiGGcshWK0+a1OWtab~6wN$FISA_gu8kaKf^-#+`I4}Q$tfRgO`$@1$K znU);;1lZ$s8-AuKkzMt;n^N2~uz~4Cea^`=u~$=GTj{Mdv)DCP%=q>w_lLO5z&3rs zIP0M(!w;*4%V+qd9mFra#MhVG7#ad^o`%+N41Pxal%FQi8Pd^t_Vm)`#6 zf&b=SyRU$-U*DVub}y{)AD~ivK8eQ!D8UtT(a1rpL%Le5rEW(ch0+x@N3%p3S?-&^ zsmHuzalY9wXP+ewkXbYfvU7^Xbta`&(6)*w0bhovPo4M28RqC~d(GNu%>!tpoVHUR zZd?6hPb>M#rJMVo&~t~J;H~e3cWskWCSSjP4dhj*H9`gkrhV_*`MN*#YbZ*}2g0`r z02)JjvAt^FaCsnKG_p_O%?*Mq272jt4h||uM+ct1KE1^$vaC8Y62S3pWXpoa+p#A* zlhV7<+TU`ErYh?14jbO18nVR&0;^WvHCCx0@m9JdfMaGYQ%y}xlNXgwXfjNdQ$ap8zEh1seiXylfv2wxV``?CAqM4D2X#rM+dkv<$xf~`1KzKsif|uOYf};&u{x2 zj(>!@UqJWRhF&cJ?DmG~S&G2s3`E6b;Akl@f-IqI`!1`@ZCuSsTNPd1tS)0bv>L@7 z(NB)#W#tp3`F0;hIsbgcbP=N~-HWaZj4H;#-VHRV`}J?Rjn6%lp2{Ac&K^$4HWz)i zS{si|I=g0{e}DBu-_%l1Xn4fF@hqEsfByw0YG?$a!>BW;*tuWB2b~{;+m)(bytn74 ztN5Z_Yjcb9V?1uq+U)0xrNLAKGneLEU%jZG?ZH<6E!3<6p~kPH3O0 zZwa}0_wlU~g!$uFgQ|ZWg+G2QfDxvXqk<8Ja{WRUb9MVA#yqWX1<1iYmKD`*MOVD7 zvOHQMdqLQ5pOo6oa%Z)_iquhrYJR@-=a3Pr;kWas*oa%z=?ZDN`&)_%RY#=`M}n3B zMX!B;Tah;-ORHL>;zQf2D~y`r)-sa3<9cF6Nxey1wqa{Y-T>JBJaKZ->XxW&*r?lG z4ZNjGOB*k)F1RKkx&J;i6I~!UI~_+?BM8RN?_&__i!gQrt2mYJ!fPOct4d9-T53~g zu}2Rpzj3bW?y5^9I7&@c|3_zt6k(BNnB_&5iK!#>DFhg}S-&!DI`;8bMp7heMD26B3Hf zMeh|)ZiZ&sh1o4{9*$w#dpb6@75BOyK}jUnxAoy635=xGQL`4&=UQuS6Nh=(?k2YT zH(TX|%{fAtDJRd(^dAFKViUn`gI0dX28++%k}`7_r5DAo)MV%5F1bykY^}J2B{O>X zxjQrPGG$EU$nDzB>KNA}Og--0%jJ1sOvm}_AY|LeB{dget`#w+`v=l~_rCQm3 zuDREJ|7r}YyzHk`9W`H0o@3zJmJ{O_qwO>}l1aUWHA8o~@ zL+JtW?)SvY570=#J`KOf8d$uxuWP^Uxg1S*M1p_yYk#fBY>GB^b>?|-U~>ow5iZf; zxj$|!*2m(|V8C>L0*E8Q`~%cjYNfw#@fbrHLOv*DQ&2(X^B_CIF6a!pZ2cx*aOQl1 z*#kB$1K|m^1hcKHH|?+xe$k8dC0_sc?TLo;W~z>!T6q_U!5a1?Uapx&;BWEWEjTRF zDdQ2hayk^^8b^GLu;q9yHt!u&nE^X?xz8XddSM{;MKVMJZ`8lh4?d~5h|+ok!N6w5~$BOUETlDF1D4s?(D^+pHf2mJASO`2AM@$F6Fw(5@h z`HpucOrcBoTFrvMA|(xd{@6sF<<{p`Wr58nA}mdf>PTIE2x}Cuxu_0hFw5-{j1i{k ziq!o926&mc0VBIA^$EKQIkv&?haptka~{FiVtgCB;_oCC*|0j3v%QeT3CdoRE$Gkf-M|8_Z8)f^f^7MZLq+oNGR8dpNdN{6qb{oG3O70M%ngIfOn0 zwZ6G5Q;wX>g2|%#Rv>X`->*;svP;6|hNiK?yPoBtWXqbH+dTEQh4b+W=tMy8dW5a1 z8oTGjrdCxSohyGdO%cOmlB>K!^K~9?wY{NP?mV}9wpI4!>rQ2k3Mro_6ROxqZs`D- z*$?O5@mjC*0Ml&C1$nqX*EPhlGv5-?=ih5Rz+tfa#g!yRDmd4QV%KfQJcDZePbW^$ z@OXXZA|caqw91CTAg4cfMaKT)Ey}I zhfkGj?}rslPlRe}>*eIwR_g$+L~>(CAIbxewqn3aGC_q>%6vk6{K5sOM0l|X@2upN zLJeX5!}c15@e1}ZXN*$-P?$hQo%~cshlbBA$iv(uijMi=w`O)`a+hV4?e}s-n zB=>37o_9QN>L$_NSY3j(`4T;95UW^r!#&$JQ&U}`FuCR`1r>FQ>Rura6tdImZqU9N z7C6O!t20{Xf=TfM?-=7#Cp-M!OL+2P7xZ!F{Y*mU zTk0BekkLDf{X1zAml4LFb=%5Vj9Z_n?s~s9dLRY3naIM1PnVr%;^Ms^1`L{*bPmDx zn)}KeQov7HZ`4v*|6ZS^W4Ew!sc@Mby@T*OS`=fQ5qzxSSsNduw6%=aGYfKaYq)_t z98t9vBIdDa0KqiVCv6V!&5cX;KOA4XfT!zeI>nA#sYaeD$oS03up!&XX0vy|-G8g9 z`ucUSrpEmsSS?*SZgy$wOL>!qRVHV~uRoeyOHMywo{)!p%IB=|^vgAn%r=IG=JZJ8 zJe~y@3(x(bV#fzxTRpqGv(z)UK!*|=e*B3^NJNtJ+&THzA>F^8KIcWR+*V}ZRdP^O zMc*edKtNFb@VAbKb@yxEg~MWsg!$_9oHU_t%IzXoBc(~_uOruZT)+G!HGN$Ek?E_R z#lGaMnmSr84!*1R5DHM4aVw{Z;pHyA9_!g2<>H6qmlCGemF{=%_3l1kb=;+)N!^qPo=r&06?^W@5_}k8BBOvijU>mekQipI;8an1*x?1HzlZ=BWVNf- zfg0!mE2e&;GZ!FLM4LbueXq^)WKtH-Ao2i#3}JI2Tx%N2bZ9_Srq3=I8>^|Oo-+6P zBtpCeJOol@1mOW<&uPL!8~q;1Sva(ORsf=nj^wLA)hnLe`g%>~Pv6gr3*`fLy_3}3 zO(E?QVB;+IDYPy6%Vy@%>KS@rzE6*&B&Xgz6l^A{gXPT5$Edq_$AyqnSx!_B5oSo2 znZA#;nRc4Zg#@y9Ca#O2TOIm}qW_`WdVE+&@ho;Y;8VQFQ@6mB?y=qJhKwx~N1H+( z$GG))XTsRBvU34RP%B51TP7hbI;B+&2&}F%i`uph@j#f&sxG?&>APe3hk`yEAiTZ? zIxLg|&tIJgk9d*r$J$k-y6ZwpBH)-B*0`G?#yVj#y`9BSXFAWE4> zq!7`kC~*^;!`vqE^%LzN&q1n9NT!Q`c;F&p=nhRudF2nBh4=DJ@pg5e-4s`wK?~dh z7%!-)=Rgh#}hjT%C zhtL(@t_4>S+ZuaUC9T1q|1H4A9=X4ng`JlP6(8^QzT{fbLL=6I@kB<9sErz^((^yb zjCgo!()R`whm69+`ZuD%I9c}ZD@Cdgkj+GuV6UTuKjcZ%iu3Uvz8mr%CEQH8h2g&+ z3wVJGG1`-F-NR%0%U$#O97fIW+_{4!g1FYrp$stfg%e+nwSW3VBj%b5Du6%DE{JfH z->zQeK`rUCxvwb#F+NVI2B9>3xy0dBd3W~2E5ZmXW^;i4o&VY1oq4To6gqKTPQK^+ z6&;$MQfvXiG*ema^;M}Fa%#%-mv2;bu%E~78mOoImRBg+vB+QYoK9fL%I0Bn^3o_G zNljj2Pvm}UyNJv?KExoBI)&xF1uW+1|V@YOix%_d8DHbLUO|<1J zAX2O6)EoEDJS=%wVL;sJfqX^Q>IwN^WtGSGb0z7%o^%x;pR)%dOHN;3G6BeoB|JGv zWpc%5&Isx1<_;!HPEk^2=ce~BC?g=3?+HGJUrBzn5td)S3mzHqtRK5nwc965BW~gR zWpm%|K!3Lq?cFRYAEoa*Utw2ZD|7ZzAXF$h9 zwcuKT+*CsukDAV+WUZ_ zBIE75G|}K>Hs3H?sO+ilX!Bvr6YF^(<=_rG76 zHr&Dm7QMJ@!0R1Cd0$99g^RSrQqjaBs(@g|lw;?=ztLiSgw2d5PEeM+{zDQcF^Q$d z^kux#{on3p>I#7cp_h6#q;`tY$|YjM<#N1d@Fb~=A4t+R+k@ICc+9?B4*qd5@hP-* zfeLK@J#Y1QXDO$xCx(amKl01aZcO4HxMv-Cg{*dGS4_T_@~5|)LQcP4_%6C9u6(37 z*eZfj{?U?|EC9u3llTwvjSRd?$FCY6Em>wws7fjJ9}EZ{3MVdq zfv~3sQj}ubZJ?7O-yl)?ChCI?P6QwaoCs_%(RGE{G^cyPyry=A8;f&5qNn$orLJ1( zG}UU#3cQpIvyq+wc)d6VkLDkq;2VbtVB12I&( zS!nENVkZq$FfsQn*QHr?;u(!cI0c7FqSWvgu>x8%t4Ig`KmJRmj*zEx)Se z_%X3+(Z3>x92Q?0lm2NC9BXTG|HR@Q+bbM1F z>u^U{bAl{kchK1AB3|S(hJu%g)SK>auY&)xt->BFk`#r0wVkNneyU{A3svelmaqt-R4eS1E=hWHx zNDh(pVl~DrCowYMraZtt8M{KqE@ri5lhVc0Wd$qTtR9)V!%N_X?eila?$wQcE#E1{ zYHmcZ=>ijWW9iqUIl8;R>ZwzT%XXS>RtK^#2oULlqeXO{%Y=0O-W=|HT^rav_{+le zI)um;K*OXFN749 zRGSG-$Q2)U4CuH3xu~P$jAB%>-~{8G-xR}Kb;dy!VVbet0+?zfjoMO ztu=MDC_e&~_fqC+XZmaqcdLepv-6jYMaysBYKlkaa(Iou9?jdvUCY~>yzriqlElU* zuseI0ni@$5ftjF8t?mm1*BIay30W`c=joPf(2DQePm`85t4HEImBS zi&>rAWd0I%9HE`UEW8t%IX(ve2p9D`#tPef_SD(c0UM*>ri+QCXuRi*y6?c9egVPA zdcg8EOTv#?DionOC%en zZyPy0@=-&f#4DLus-ud<+4OiWH7w{p;>7G*i==yyfHad=ME6jK{7wFMs2F{wY0uQm+LzlROAKv@$ z^2G?%YwAf*LBbZvUN%Nz0DNzuh}awhQ0Xs&N?+XTL9=4rP&6+KUNgRydAFT0C;0D9^K>PNBX03Tgr^ZQ=U-~7J@8qZzIg_&!( zDDq&Bl&lB98X#5B@G&f2pr*@nk2K0hJ{{jA>3&t|9hV8o{G2Gk`~H1)PS)GPG-=St z)04SbA#?gLzEUb+y$R_1r3pTUozpGdsk5CFu@8q0Y@Oh~8)s-w$3;hlJx1I#QB+Q4 zNxxlTjiit{r+Px_q>@1c4^vgBA$GZRF0!K}P)#_n`e#+q3P0KWQ>ug>qY?M!u3P-A zSXpe<>`sAO*f)J-l%B4A52IR#Pg974JbS4^f+?ocyl;N;V_!E%S*hBDTKL}-8EvC~ z_dU0GaCW@N_l>uu+=(exEDU!K$0LZrm^y} zO9RdJq{}gdg3P|YT)@gGwBKhXCd>L!+{n0PEW{21!4vHcVl!){TA?zKS9i?~(Y_~t zhwRc0C{3W)7pzzzT7Vn6B;M90J>^(D^XsYap6Gv3{T8t~=}|G+)*mXM>}#o5-~wk4 zyNLxrnD-P^IR%yapbE>*&r|_2t-jLCjE_FMPM%hu4WHn%=M-S&GNUen>0@H%)%c^08 zd^TX$sooMU5x#`5rk~t>aWy4{A~GryxL!BX(zCUfhauLD=$<tuLX#cAEq*y%+OO&3T!h3XuOWQPx|OWd`&Z%*t)R?>o=i5;@=zu z8G-W$yPKb21QMM->Fyq&WzEl1)1+%Jdw=YV;ELn*3OC%E#ZX*m=e4_do}4^&$8Ia0 zkhb0-s=TY1ccePWpN&bDY~;7pkbpT_;!w&QWM8xpHLP3sBZE4at#0VMTG;-~Pa_&3 zvXM#WiX!aj#|^4Wd?xX1Khi-aq$*Rt}Q>=*3&dpPUSVTU%5x9!E&t5-9Hui7#|HGR(3VHLF%aAu8#stdz z!Y6l`0P%ZXP;lsu4nqPWub=a)7MmN3h}<4T4TyFyI9@=trao95WZ)wk%^-K7_h>yT84|SV-5SY2hMnyrm%~@o$-r%G^OL zueds!+RX_?V%SO*MWr<~X3W-QURJIe=&rF5NHlwRC2|9$?awc9_W+VCMhyv}^h%YW zbb+58F?xP4s4X!UfsH4fRMoAmbKou0((JH##C^b=+AmK^xwmbKM4nCW{-&EK?K=~f z8#P<5Gc#LxLLGLxr1@EfG@lV~yHX}oAzP^6d#rC%xXh32<2I`<@l_ZS`iKu(_z~gS z0TgXXxIKU@4aEjl*4s>P1^rXW+CT!DV79;^VDi86CD9h~za4%g_@^vU-5`lW1XpaH zJ199dFSW1^0$$xJLF~2ieU1BGl_1_Gr#!@6FP#m5kn<1p+6}v`;G5)oa>_Z}*XR9( z-W4%4w0jYKG~}ruQP@TyfMFA-tJA@J>JayQ#fF$a>BnV_`q>jd8Jpa`I zup^QiCwJE#miDiCH~Vz3Ym~EM*sEN@puE`VZgGiX6k~?WCW97)WKJD zKo13>E0|tZ_>t3Xp(zi6Mk0yCRbl3>Q~ypUkx+0n)fSpd+;=Ih zsPevoxK4VUV11aR1|i%{Yq>?@9~;`Gf|Ac zEmv}R`0UY#`KL1OujyS;QIx96o}b_4s<@^$KHeN+FX^+tAIfu?Z3vizo4@Ebak;{F zs*j}0lAO$g=`fz`6?JXVM7xcU;5CNi>6W>^-(V0*d^7s@8F~TPNF(Ry^Fp)Mylv{x zQV}&&rg%zxS3>$m?d!in+g?7Z;dQIKgqK(16s9L~_Bb1B&?yt2LVc~Z%e=B8?A_2Yiz8KB^kESWVf3HC^$~^9Sp`Ctf>?#(r zFZ))J;~N+#!rFD^6TI>InR;XNJO1rfDGC`UwO8$ zeu^i4wxzfqEug1V+Bnnqs(rP5q3L*xkWJ+gxio~&J+FFP4nZWOW^~)hFci=d*Du z_Gvd6vjB&@XMVOT>d13mTL|n>UcoZ0E(Mb52R*;KG9yPkG~K+GONi2m?YT6&H9gk$ zN|m;vpeIzh;(RfBjRa24Nu&dF4bqm*%%DeBt|b;gMQ`{ykRiHF3hw$ArgtD+5GdXa zbHWcUkOp_-nrNB)Wi~$L-NWv(+Aa|CEn>kSgM&m;!CZh^<#bHcgWOyin4f5W#7#4 z+enHJS9t}o%-Q)7yK3ie^@FyhhI+gC!@3(sjw`NEn@|1YT5k_^=@jxj#Hkb-6WvzT zI~5(W_C%!L$NoSrFdAtADD*g^*z+L1lV0l1h4Mi0N((tm=SARNnCExjsMzg53}Rvkdc`w{?S)9sGK3E-icN8XF_5VD6L`jpZnFqx;L#0( zSWiPkC;4}byk?JfPHp$qjDZ_DwJZV6`2eCJ%{+iZjwB&;1=6bcZW0(I1lw8!lrWqksqKE2d9W7m2l(0)<98luWEip~$SsYG- zt>sdbDq9?U#>!EMg8ou+=88QKnyns;pb>N@{WNV>do(cxIeFK#C?Mv9G3m(dMW+Yl z?$2$v8yPeVjC%83pf%5Y!N{&Ye@isxU}qQw%E8mEe5r0m20VBh1XojbTB;({xr)xv zePZ+sK>xKYY>NvM{aor?{(ZP?FoffX-B$Z?Y(%x~*cS#EMgu-nI{L}#6irmm!14~;NJ-XEnuOWFdruV~k2MOm{*U+A zOLtz>ck%LO=Vz%NpEB)7TO33(goeKE`QUKDd2eAmMg)4)ZkAisU8=ozk2+#6$8cxe zcyH8>Y`5vU3^3#PVvn2d2MEt%WIh-8RY zZ5NCcvd&xK+vYju?3SzZ^*BCj0MAigIv{|yn(QHo(aC5cXEJ0l_c~|dGWV+%C<=|E zmb%|BGXo$1dt9Po3tsKdP&hM^^CVppsGsmej()(F^To==%W};0??4QGycNe9e%Ja_hsX^CKPbc_(AOYdcY}R zk(A_;dzjoUS>z+Nv##!-ImH}`HQkq{8=lwbFb%!AvmN4W)X&b15j+VvEjtzzKc%Qr`TNOAJvQ zSF|8&$^8@N5&dm1mz7n%SiKV-^^F7bH2#@ndQ0###zga-(XZmsbV)cN!Z1Jb?<6ljk%{2V>FG)6+tbd{F!5ZO^Cj}i}jal{QU8!b4<7Ddx5v6G%C3Ip!cA2K7ma;Fvr~Jui*RuNk*a! zFuX+0w%ewDgc{n=?D8aYDvw*kMfx1xgc5MRiHb}nf9lf`%6INu=zqqIw2+0%SLqhW zJ|YM0pCe7!c54EfLyTV{?4{q!XzeRWNkCTln~0ptg$))9j%A;)k>gl4WL7VbXFQb_ zffm5BL#!D!U47y)P$Hm{=?^$vwtXEWd z^3n%wxIG|@nQwlduw}Y2>s8=g$h>ou?#`79z8lGjCy0a+nn_)8uWoQ;g75&U$`0iQ zAV%Xa_LAvkiX>?(gt`0k=<#zo#}y-+;xWqxXwl<}Tj$L?{y{k69;m3iF*A6QgnZ;r zo-DHLWdUZeUWLV6 zpZ~Ogt=+z==vD_eI{J(=6*45x62B_ve%jhI@3#g05g?eGv^ddXVCFeJn#m9o;yETHe4JkRsd=9`-E6)4^;$#Krmxy zdus9H$J=zXBY$6n#c78u&Rg+%B@Yr72d!L#IvWIIa&A&qSvL%upQfLSEW>ycJ{e8Z zmx2_+m0m3K?H=hxA-BQA4N-;~!n!)xtR(8|mODv%y5O_MoSx=~z>eC#cjtodlC9e? z`V6jHx#~ja{l-xMb{Nf5C{c#_$qnb#xpG_jGC@ZQ#py>4`(cn2C6Sfpw!MzC?jHYb z^of&b>ot7O;gyJDvUqm)-^SWUal5P-9%0E+P$>1hQBC17>0*)#`(LvaM7#saDvGI@ zoV2n&JL-kA0fhBsOwbi69_L9}ShxCj_|SWQtsf)j!ry{-zulSc?YaKWM-<+jZ+l{% zBWAR4~uXaTjk&Mc%2AshMY)5W^wfDkVqU`gzfn~*Yk zD;dxZlC+Ip_{Y2~#!(&T)qn`KS8k^$mB+_0n1%P`vsT`}<35F-M-z>n0@w3r`-UVX zW|>dicmHREVn6jQB28;Re6clE4`nu%#s;K~Yjyz_$hx3Yr@l*ZF@R3$z<2LdH?1^ZfchXv?5^^7^+mJk@(`W zA(`%HO_h~iJx$9H8uGH|8S|Q=Y*!UTPM6z$D=0WOFZ*OsMm8e7G>o*eH+%EAPzUXc zx2{?R@(K!{NpK(ccE#0~Lv9V}!(3cc>TW>?ADy`Eo7Gw^Fy&Ph)7&*PM-9&T-6v`~ zTtOgCRcnMe+;l+f9dfq7cOFwuUZ4YNO*m-ON!I5w_Nxdi5M8dSIyn9k+CXa+7D`KN z-T-1l&(~yqBsDOek|yz?Bzh?F?~oH2tF(1-JNP3&I9zSS&@rg?<_%^sX0WqF<)2#& ze>m$adIy7!0Qf?Su(>b)eU^#>mu$3mH?7-X!euY6J0XU^%XKX+a*Vt5(l6_+rVD+p z_E@87v((g*vMA<4?U=D0yZ%xcDEa%h9xp$S1R8wE_H2O}4T+%d1Y<`qsh{Hzr+-YQ z1uFmXl*bg5mmpwHdbl&=11ZvAULI(0ryMJw<3whRzb-K6vMclD^Odx|bx|s|n3*yR z2Q^ty9~$YxZG#0T(by&@;POFySvE z=f7cA4liFH7>PoAvwubcPKe0Mhk(ZkR>2n|*D3n0w9SLu#&9mVj`3h?#eo6aLS{k6 zmX)%d-=Q>OYj+`P*VNZZ3jh2>Y9{?=NmXJ=DTC6RzRw)>E720#h$m|adB#X2DhHh$ zL4Do8vD`Njsmb4!UHeze;-5QAu=KM_x|@7S-a1SJtnI7-xs=-!ie=bR5M~P z8|Cz31jme}x22&Ny;WDQmmRBIo}M#zUs|XBRLro~0jgQZGrc8_R|Ygr3lE6OGiM^$ zdJe?!Q9xuWOexYaRwyii+3Md1c1(e8o`0+8r7v9XYij-cskni(VcY3Y0thMB6Fa$n z_pQV+?x!vJ(9Dlj%P0K?gHL9*(u4d`NMikt1w_#i<5nF*={beJMON#!@tBN0^qzmF z5Z=yT1NViZe=G#!^LsZ=6+14nz%QfeW~^gkW6OtjoQT@qX>@mI=O-sC)}sqHxTn6; z92hpf3fBl{{Wb<|_lu9GIre(3!D)38t?Jqap8XhFhJ4+8+{zCkI0$-cZnV9|OlGTN z^;vpp1bdf``TZUP{-Nw9vAw2{2C}NAW$2A%AKVacLNs045Uhf*#zj8V z0l9b_&QJ})$+DYjx~98^a-0q*A$DL4z?ju+wz8eo|3uM7O-@NM>jvRmuwvZ&)i#XB zcC&VK2vOoY07m-@eK6>?m1Q2QE!m;fs)1cKFC?(MXxUl9<}u!PQ@FcXq&mAKUr8Ce zo{MyuJ+gvxQan0bA;*aA>;5co_<74e!^opVJ(4TQ+P+MmP-8@|CPnO)c+B2|jXh(Z&|*#F zGp}e+0P)SnG##(Y!N<|RYs`Cic#aj>WG5r-1;(zRJPp4|NuC+e3p?4^xW`3>3j%;( z$p^?n z^D_y3zs~={hLVWy?gf;rx?9dWENTv^%tV$+n6ED-L$hG0z8)d+?<=vcpoygc(Fok| zLzfdq#O|LXqKJrYuGDpGGHEQ6{NHB$aSAAJI=iD^Rkr==n~-U9DA(8hWSlc>SS5L? zH%|*TP~Y3rs=At%bNg4&Oq7o0NA*5-j0fyVUP9e6vzl;N>|SstfGee@YY~17_qq)t zGfhkPXaau8`cMuv`l5lQ0lxarHF^wm)i9O-;`gbJ{-0C6zV!aey<;XL!4G8O7`h|A zKY>WJF-g}B>P_9aDk+F>(qsHR3XQ4r3-Wuq_VOqL$GEEuYh>ch#3vfB3=k?G?5*Hm z7bvXrc#V)I3Kt9rG$X)WTx9LH*71LD&hY{1iP!cV=uuM?6ih-~@|AOQagmzbH!BrPMIlU@Q8PaLCJoG3_IiFUtFx#sjug?CP=y(^RkumE^? zYC0}ZD+=6u3>{m%O8w4v5y zIo)9U*)s-Aw`>x*WBASE9XFQvK)`X4QRJ4sWmN|{V};_-2t%!8Qpm#^a}p11Iv=GLZ}G*0T{*S87MU#bzyNN&?L7MM z47I=mPqGDIbP{bfJ^qC2Z^R&P2dBr#M;dLhp#}?7;UGo`|KX3|TJgJ_qe-@l%K+Nv zkn(Fg>$hz1F0{F$^%_ud*-vK;`jUO zPX-3A@8)n=v=`J0`Lu{A0)7Esp+GI_m5Ro{Gs4*^i={VY%NI_3c++hqI=dOQq*dyi zti&8>a%#?SBvNSL0pB?b;C05_cCD;-T2w^x68ai=&-Ssgf(N&buv!NN2XT3s=_N#( ziIeNesbM}p(L}47on1dBzC9-DfnV&!|IDUvjMabO#^qW8$Gy}pT$Bjy?eEV9NDh?0 zD)*g(Y{(q{bK2ljtK!PiMo{IE2QGIoLgQ-n(dyY(3F8$<2>* zDo%KJyrRq&2ga?)AbJRayI&pxaE8$;!+Fx+UbMP&3dpR7Y(sT#$Pi z!gn~HziB2C#O3DV!gD{Qlp%SembRf|8M}e~C#^iaJZT0tE!bs!Z>y)3vF@^fb-|MK zs6^Z||FCD{!bKx)FN+9v0lTLpDoB3p%l_T0aCT{6U&aORqPy`^hVW$Srq!y{D^Hml zHyCHhu)BGPr=inO(MtBg9+<_3cu$gww6QV|Q0^&V1TC1FXThlb(_M8(WeAVQ)1TR#W@&Jn` z7*14qON^IU2AjoE--$!CL&EKE>T_8N9G~wxnKdniLk50$Nx0p;qP|&2@ezJEBq4J$ zIwU7E|F=2|k*KsH3RMx3@#m=^@xCbuIj%E3zF86B#oxc1n&d>9nr^+eFY4bSat`3d z^%vJ`W~L*Ht3I+|ioUNrPIn+Cr4=H>Ss}Sp^kK^DyYvzw!Ncpz0h7rb_2=Id@Y1K& z(jePMG6Yzcz0!9sT!%ApcsGC+B-|wby_tIJ zUF5}VD;&vywksiJu5^*Bsm=W+Hxx?7xM^czojZ1*8FGM9DJi2-Pib?$HPKs6Bb-~t|4>u?F%Go(EVKZgo{LGA31ZTwBV*~_@5^izu z#GES9Jk4|DkT< zp?i`)!Go8NC-YO%owFJ05Mr>G>N%{gz77o4mQ)K<I^`Pk+Ibx<bY)nX3 z+gya|Hfno1xQ;tcDWm0*TV;F*Q{mosY_WpBNb*o zwRcec2Ducq)*2cGckscd3;%r&com7xizd&$-&PMWd3--L?Zcx-juk_IYrYN&(aLyn z%;j~cc4U`EnyD%CHC6=!&-FJ0i)Sr4a#$K0@wMg&mfKWDyQ7I=%-x!rEV>1Er4=G% z!^)>8Exx}vLBsjz+4->Cy}xOv-!J`2DvkGSu}JTn?Mi%mjbfy%uzfJX1J{e~iEx>h z^e~HRyb;-W!|lmu0Mz%_R66zP`EsstS0nD~rcpoP>QK#6=PV&)v^X z64Osg65STTOY$g+S&T8_5o6H_Yd0Hp9nG{bp<3GJs)f|qJ9K8{79ARXq+>I+YrXka z?fBv|c-?Z#s=5sZlOmZ152E%r3lebOc6^L^s4SFWe?9E*ttNIRFms1DUcNw-c$_`X zxkRX*@zPq%J>?WJ{SEgvA?Md2os(ZDc=Jd8O1qg(vIr5GNgCtz`OimE5Y_^(FrU>% z_O`A;ftZE)Q48keHoX+-ZG8!d52b=j00RcIlt?_fh zPd@&x57lSf-mOrOUtbF3uxk79R_IYb51!`s zFM&8q$vo`lwn&A{zB$Rcj>#IVY}9UCiOEh-G2(dzB7YRR5rt6q-tTMHuNmg``?RzH`! zdJ~s-+$q?ccoEq^xnNp|{?4Sg9E!PQ8kTydq9n8A>+WVe*SiiL<4N-1*>@bJtVJBo zv`c5T(ZiQviFd^R-XoaQ>U&ocPPuyzzu6#q$Z)s}U?mWdM6c95VPw?}uJb2B>69wz z_2hM8jnFzno*P}?XFGXq1_k{5{Q3-(!;0)SZL4<119huRUJYqp-rV)aJ_B*2Q=G$BT{B-0X%Y)4$NqkJ3Cjvam8de!MOq z`ueO7$IdG;y-ylv;_s!Di3_iJrQKkpZVpfFV~xzN{xoH9P-S1e{{(-=Q7EoXSk!qB zrHf6uOY63HJANp9{rh#g>}-vcGaO>ajy-$INW}IP*6Ek*-O8uU<+j^BS5s!{q-*CE z96EU|R|Nb77kw(7?>)}W7g+U*`yj50A+Jm^)!RagwY|NKJS$wjAusPRUOLtKP&%jB zyODBlZ7cu}%WH03fusB7i3>LK9V$i`HzP0A;|yq~gjRFCP~*N&E;&dul=9K?dFR2d zEZ5%Ik9-sqS;>_mOntCCi_GiKnmW%@hVO2CTVAtNSA7eA%Ph*OU~c5#M>s=g<;IpM zcbe;n#M=J`Oo$T(45u>nXd;?QIX;`z(1$beE!E|&>0I6Xf^7L4F0c7x26C)R(4Mp1 zgl_Q!o(RFuGV!+JGm^&cBkR+vE)N%&v;|CQo=a%e=o2ya1Ux{Nh zx1_&pitjJQ-k}B&L2kH)_mcyu@=3CT9B}s}Q$ZMKWrbb_O!b|cp%*W7Ir*x9=l#OZ z2{H9;WEj|*8`qG%5i#-OstLeU^m0d&`!2R zYCsE&SGS+v9Z}=iN_U~XFoj8Hq30e-o`vNfRfM6nx$;t_x~RuyNyXXANUU-D6>JG; z?$S6X@owj$(PnLZT`8`2fD62f@~L}|FPccowBc4QW}bS_y&Yb^FsD0SIdRikB~(Oo z?P~?WdHejLz{ge#v4S8kepp{}Yhn=h{L!N7n$ zZ{DA0V1RRn6F5e9#B~fa&j^?1*txnnrBz=M{S+uxd2nUVayrmseKFclORY|Tp z&)gs}@TT&ah82p3H!lz?K6>OuMs0EC=(hV=@NT{jf3(te<<3Xgu@!h}MJl}_)Ryrx zU*i<;VL0or)b3EewlI&cd$x(+NG4m%C;mdBMH=&LRaE}Zz&hKE*}4TTKYDZG>1ai) zg}PNJeYd&~;T?PRzDIDJh@i#HmX{dP;+wErwfW4Iq(4E^&kx)XEJ2E?ss2jWJi=+K z;papvMii!|9+S{lzgYaBj6im(C5M){88I}+$o>RC+KI%9ItGR4byP-3oNYF=X?WkR zsaJwR{T70`ZMW$!uGzZ%?mGVGTsmofg>;y6QNETi*@CtUD$i> z80|8NS7&^IRE*9_G<&>P!KzJ0XVwm;+OYl%O|sGcgdIy?X-3~>`L}P*i$&b)Ie{3J z`zGP5wqed&vhVltKW{Y(`nXS+iaPBWkkIUXv@g{IW0l4pFQOS*iH|Xi-HEoMjX8Kx zvi#b08UOX}ib?+gf zq7adyK!uFVbSfx|TnVU2f;L0ct()#u9vevkMUTfMC;BW#BFM>KOn&%Q=0t6FQpH&6 zdHn7KgUbX4ohJ62bija=t|`AN&11B$p4aUs6*S>@?cI(ijrZ0+8&I=EDN+!;epQM6WS&$$J-8lx|gTMLk$E^<}Uh2|VbU zH4fFb(Xc0ZqeRbn?_EGhTYv)9EdE(vOsUy>mQXF9Wg&RSJA!3G?%yvO2u+c@EQXyA z7c<)KY@*Us_5SYILc1o`tEp~oVRJCLZ^M3*O^R&9J{G#|>Uvk^swCt+NS=!2&wgT; zwOfDDOW|d3r|*&|&-K!bIpe|-{C6Bl3x-0T&aNc(@4wf_$XW+b$J~9iZ?=s+y=Al4d*Y%6k{JYs zW5dFEACthEWU^RE5Ot(@CCl{!{7Na;ay{(r?Re#>rJn%U*4MXKA;Q3uPu(#<>v($f`G4wJc5YqOI3f59PY zAH=kdE!54%9ceRCg%FNn7T=E|X;uVDtgq<7{nc~Lc&x>4!p)A(`Ah`EFfuWTzM5hk z>*_e3?=|A|#6P~hO43+kn!{ypJ878C51WvNQHyNSXFJ**-bnjI*CvWGXSezSxp< zkovNGPtHPPiAlHps-VOqBfr!n<7O1i6(m42?zD#kC(DU$dhXE z{CU>ZBZ<7|XyduM8)1URUc$$Soqd76x7BzUS1v;MOnE_YE29uOKaK~*2$R-PpX(X3 zZ7d|+FHMa9+_DpuYl&Hnlhq4ta|>+nRmDu~xgoRE97cyZdFoVWQBp+4kg(H0?=SV` zywXG2bjGdf(&Bll@{Sid_l6zmVY=SJbZIgAN*+Lui$Q1;;>ELe5^G7A)ziL>e(!hP z=DN&eD^=f!va~W)mmO_q&rsEmuG2L>1n18!ayxdRc&{v54#C8e1N{5#f{M=}(R91|A^;|C_oD|hGna2gR%$vk?I$k4ty2S?{lIr49O zsT_dM7%tK(cboV7gXbl~$|@=EY_XVUXzUl}by4(i^w-a?-4`q~=ed7q_rV=ya$Z9%XA(Qq23#ps-|t!>d%27KUuMLR98E$=DxJDHA2P0$VXpL+Zj+7{x1U3y1SCVA_ zUJcLKU4zmg5ghfpI?2XX2*4I;SJ8ODUF?7VZ?B-by@XcT6=qVe-z3Qjv350-q zaG(%U!F@7^)P9JMF>1iM2v#2o&$HvZs{&&(SD0sfJvf*YoUspZU zHo1BG?lYxq>Dlnu67L1NwhZ5uo5hXOPwD3WSg@M)nAVuWbM8s$M&U6?@sppIm}v#q znf}|@+Bk(FR~;H%d(@*%r_!BTNP62T7OZN%0WWz{%&Zhe9PXVu61qOS)0$Tj3vrWyROwj z;XSk*9r9$FiO+3;jo+W0T$jl7nS|)LPwx~4_iy>_yXnbK(vWbDm6BfHp1Q)0`;-w| zu8bEFsMu-TurQa(=GY#!9AC}flgeqf1*b)Rx4Ct_a*;{ZC}b=;;-^sSc*I`G9VCDY zjy;F2m8hOdy-Jg}RhBp>sF_+w;}UPEqh7zu>_(NDf>o1q$=J}i&^6<4>$v((OIq$h zPyO~8B-$(b(j@#QT1Q$VLSW)->2mdM4R|rXF6~nup?`d6Kf^kc^U2a;MG(d>Y{o>5 zNgx(AP>}Lu)d+zNBz-U3=tuYMZ3|8|u#HnvSuU3zV{(p$r9?l^EJg67=oHXEC3Ja{ zH)@@LQoGy^IW@A8=};^Lz%of|bh9#y>x;y!FO#dr(|g+m;V2l=PZx~B?1mh|p55uB z;=`Dksmei>S5P zMRadyxR#e!Z!ThQB~Kc)cGa>?%G>0Q8(&~--ZT*yHO4jG!LCJVC{KFs6gqOd^UBMRRCj}!vs1tsieIA z@$L#L97?5MEE}l1(rIri{h&<>S_|$*Ix8c|0)GZL@Tv=$U%RH9AV;EwE40*@e$P-4 z&TtX{UD(rUrke}MEO3-AOAx*@9kiv;pe}_pe#;yILjv}IFPO|3zeIe`rr{au&mrXj zH%+Fcv~3Fiv#g(cfx&1d!wz_9aLnb=l{+jL6Nb~kIjZ_6|8jNMvrPs;#b>vkpwBH{ z?e5YWN(FD-bM7ah?d~AlkrQ-2q;1T0*4|tRW#IBIN9E6A%*uylV!qw7hB&q2$?@{3 zxN++vbcQ>LE}m3VLmKgW4QkjhTVWgu4C!M z86Nwd>n>|G^r;ysCw7Xq3ckENBD0AeAH!%!y-iqcEuOn6!_ejNlz}!BI)?i-ogk5z9{l19i2nz_-{Kti9(R3~UY4tu#S8Z~3U@{i_I%$n3Op9T zKCkjPhthKy`{!Isr1|zYtPRXn;h+f!qU*i%ZszD4bZtfdwizRF!Ux#EABrKd7&Q=9TfWXiQcC_Zl@rC*B?ar1ihotbBV~sSk%OR27Va>DinQQFaO#5V2vQtZ$ zTdRYDn$JGh&(=_0NIfI@p5jhifx%$S`cC60RUc~9l+yDav!_p63TvyPgm&?uEiC6p z0o?$$>l_ebJd*#pLeav2xyMXohueq|O-?M64~cy4HK^vU{=K^>%49Zj&~XJ_uBdCI zft%&|R6E;!&$295v}~uOgm~Y(`Snb(HtP8S)^^l*aw_v3hlb7lcyrXxeZ!6q*Jp_u zPNHVNU<6Kh`;^G`i=LfefTH;v=sWQW(j&4o(8Rp=ODB(S632vphp_;A9}VPSwY z?Dw&dM@i0IsSZ>~nCt#_*me_laPG#!5IdX>TpFwUnym+02EZa|ifH&lcX(R@%KnXW z;PfXbO=mmb>Xr$O$_E5(c+yUuQq$9*St7WQQYaf0S~Ng=T>xQEU5Se=dH4yRt`t@I zie#Z(-EeYZX3MyfXLtCZAUq!z|5c267izx(5;oOoKh(b8(GeYq6!-$v+jt;RPVYb) z&TT8lO?8VXk%svJjZ(6eqqU1xw=RTnIeXVk`dZ`z7||AtL=;fYKwG6mVqCIJv@GmA zK2)D2`qj#gbMba|Ii?=wYA^^796`^5wEKLp`B3zULR69yN4bQkz<8ee!Q;O^*)Mh} zFl~!w^yZ{Yzq?nlxH+3`uZK_n!nub3w9vLi%&>^ILq@&r+~r!TMC(<#|VJ?y5`p@tpK7dICdw^T90K_0S-2R(;yQ53xuE`n? z9p;yO9#%?u4%eHkMZz^D$nlT-U6oMS%!mxgoT2E zwI8FtWG;czwO!pkCRM3wjtAWu>vfiHkX~vk<6AHSfs6*Dv$n#}sype%48V>=m`->n ziE-a97yH4u+04%#Np_u{wK{tt zu7wJTZ~(YD;e%W6SLbe6lLJ$QsTs7N`XRa}VJhPVz!fro_5mJTZ(kvZ`&K(d$%r=KU!hItkvu?{EHVRBFa0)fjdRy z9~c>t5%i8mrzOR7B8?7v^J(xUfvPVyEovIH^>+tyo($cVp^{h>wMhnb@MS3=hG%%6 zM)PIrGAODekumi-yWSUB-g9R2*9-O=s+tK~?foU|d#gKh5%zPL#P7=JFmzF(+NXj! zdqz2h(|AAO2T-SowAsPE@T-!T>Iy(})pS8yi9&_VLB}*Y`Xf&MBW*VfY?|Sq_^y6M z=&4xw{sivtXDwdZ1^b4RkpsS0O?P0W!ZODz0{|-6-3*}WX?4VoFt9aoJBR3J8(&N88-}5`>c4N%cFOyC(|TgQ3jbAE_Rli+NC$GKb0(qRbK>GAxXTi z%8Kl$_NF--V3kk5tKGsDJzz^%>*o z>V~)*kXVTpdWUb%q@^a`jv$dRI4_gFOa~bU!p?hJ?w+A#Go4DFp^qtC_L8w!e*ZJl zr$h*WN{MzJ0D0fy11{Vnv{i(D=}JJ=bl2KyEC09SL`(M)quk0Ow+M?cs;RMe7fV;X zT6XId$P14URnYn3(=LDNF|AMR*%dCLXC&lWJYQ>tIGW#%u^0QATRsmbk(O_8pgXww zg}Zq24Vov~i7JA}Igo{dHnXxwn3{&#eC`6Ug8nW}c^HDWOHPSm6!u}_OmV^XOS)mT zlBBiSP5suU>vFVw%BI_y!<-GFL0 ze2{NYy3z#&A8!*IT7aJoh#s77Bn#c@+Z3g#{&BQSqS^sDBxGwfxvk(r-}wS0hBE+7 z43h28VH#(qRRNR4kOo`jl@Ae-sF9d!nU&+Za{WXz@u28poG*{v$`jk>`WxTK;RY+S z>~{Gw2Fv8A%9g#r#zL@b^3+0My=f}do1?yA&Od$aE62=PhPb+=rGvdu$`Jgdiut`) zGoZ1?D`H8gsryyz6caotP4JZjZ5`$G?ty|-*cyZ7)zJgW#WFh5_S0`ShXOAp*vfZQ zFc!@ObfZG0P=U+iyIcYycYvhz^7=>dwa~+bEUs=|z9|eU!enL!f#!n%R9UTX4VoK> zo8R3`eX_`C-j}Q6>8skeheKFG_Z~}4-PM`^ZNa9q6XYtsJhP(Mjcph065}`H;lV4< zg&{#QpM`>Pc&%D)Dm1i;>lf1lMxF+l6GfEa1aa)?)2HQhbA>Bd-??Z=fSb_L%*y~% zm`O89#unm8UwXsZXJCNokTEcb8-o6EBxS?jZA|(dCTVAL)8g-^ojT<+F4f_Eii0bR zjL7bjYvnP=xgjT#Vm!pC6VOO~z-?2gDgz$z4>Q;DgIT|eM=gfG-<;RcO;iZs%>Ie> z5!sy2K&%=Ed@6)QMwZeUSp}yN+P%5PA&=vW8&``(Ao1A<7!Mss4 z1-#+U%bkEcewNd&9kak`B_()#pjesF6tuhz4=DSCv7{f;>zEFzMDtphL`6pQS){Io z3l-j@5OrFAk+F*@rm=8+37FAV| zv~Ub&SM}Cu=_o0w8;xzwJr(R0xLWTR^M_XU)0h%Q-$C9-udt+Hx(-Xm!q9J#t~YI3 z!;-|k;OqCN7}fm;gZ6mg;sr0$^M*5G?^RW&;`oQjw_JfUGMEuBvVd8SJP-Xi4tBDi}KviY?1PwP5)Sj zA%VU8>zW(S!4Yx6P6inTTA+5?hR^h4irIl{Bl=Cz!~nurJ-^!U4i7 z%Xi*h%H=Wl@{zD+@A9!@pkQ&T*ev9YDp`H+7vA#r?MdtW2!*%c8E4y+3qjQx32((# zViJf+GFni@R|NUgA-spMf`Wnq(TG6&sm3UhPU5sVGXkZx!HB_JCubJ)v@ITev11Z# z43q`CW|^ihXy$v&bS>@KiH?7)`rcNj&ulYO&wbutCVI$ip0~TZ>!>s0HcB_warGW2 zYI}&d>%K#!`R1L8?hBj)<$3_&bOds@aOoh%>gP2gUAf|qA7s1e`a>xu|N(cg0NSbxGRCpOiVRA~%E~g(?S$$q z%t1lHtCCTO%i)P7G6gA4TMvW_Qi54%-?FVaZW-DD1)*j|dLpsE0PzbeAZ)i14<9V+ zSR(MD*Za3OdJ(Yy-;pSHj5lPv!4XqG+q3vBeWzyU+$3wY7LyS$yEBT0MdKIPHiC8B zh#yKxd&{)FC&BqV`5k5TzJX|YqHUkxxEAT8s)91V#93%L%!0iNay{4b;T5fv(9mG+ zwvF^_*Hv9msEWd3WuKF2o5xS@!pZ*@{C@shv}?P?ia!* zW{2kOt#)lturr7}=Zbdn^kGP2bKT&UnH0K!s4x<}Ee37&t|rw%F(ZhXwTm!*>Kxin zp6pSwqiv(FUb}hipLrsiqkgAPvlmB#Lg}Y=Mg+@0vbzfPcI+%ND#s7VzfeF5kXK&9t~V!Rh8tGp`Wns+Xrmv?2` znRrlWeJ+=x(C^Dbj&;UciltlH$O-s!)9pEz`$dhV>M$YZbMs82fQ=f_3ukrww=pHJhEfRUd(dCR^201o#tFB=#)4WN#$P~ zUe-|N<_-!9FyP_-NH;S}QpV5D-T5eB(c0rp%J7GaGyG5fN%g&8Z1oR$WoO5WMAH`B z_1E)6d6J;C7Bv3xb_cV;D!OF{sw)Gd(v7ga{R+K#ZUJEwSTV$`{E?g;z-ro)hD|L< zWQpFTpP5~s9+cTz$}Lg*x|SOmzGB%^YK$jOG9)$|C_?)O8UHS z9S*Aqd;~avHF|w+xLgar0b)<+Nu7FX>8Qc)B+OLrS{pW2>A>K2Z)n4vtHcBfUUDdU<(wFlY=#FK@@0nVpC(y=A>an=0a{ zdg|PP{Ud)6P&H=y|Cymx(4<@gnzL~mZ8wNqDvAMY^!apCJgRipqJnl+bo)MQgzdSw zsl&;yNd67Txvx~AC>GzD|BqNBShx${|WWM?CY>U?JV-+oF;#KS`9p6d}V z)zlLW(al>EVx0vjp}fZ~et-TDG=4BlEG<9x*j|`u{xy)cYBYK=DFKO?$psVuE;9pZ zzCVPj2T&9lT`*=1i<@N5ZcvW$6Mf%N_YK6q<^i(q2xFmz8Kx}>%82D+OFEu%|9VU@ zoi6^gq=m8(b)0Fko*ifDny4=s`vF>kpzWF3@G981fV&CW?D&jn&H}gddu%iis*vBc z;q2vv_}3eXp3HfZmFmAR@Zg&szD&bEW;4jS&9!qSK)oXUK$iSg9P_Q|^xW$d41E{> zzNrj-c7fT=tKM|oA94aQo#1x3^;v2LhSzqOdGNlia&c_@z!s_zsp$-$5epUlo0E< zNkWfX+9m9)McA*UnPR(hsf6P>q2&RH@U}hzZ*q5`(|$N;*mAxy+<;Z?CM3^2>Nx+7 zDQb3hMs=xO(xd1l#6BAZqQQZ^k-ile`A$4BlFRGezYc{n1IPlynkUZ#mgjOmbYk(gu#k@vZ%h>(@X#4ew#aH(GfvLrH#d=vrTiz{u{biAkQ>zBBvo zN^3#YcSYyNv5?OXoi#JZI1i+x6hI*x_RT}Y4uFpbNYECneL+;Nxk(jX??FdQBujVO zDjvkds!nT|3R;B3I-?-uQ||j4Cu#hb?H&*I2yH646`P`TNrvH}QKYV-<&?|sKSB&n z8x&3$v;`{G?cKuLf4q6D?9{~H_+7|z{p96^piNf|wmv_5F~|>|i+*AUgHRqQbiq?O z(t_~??y-31y-;9Je%heg5x%EePhDUk)~xKgmS1aVP*qY-Y&ONa&YFWjALPyrO)cu` zzKjjigF1sNE809>01__AtwOULMqf~(f0PO!&%a|0dtvHr;ZP2a)Sa(_0qJm4Yr0>{ zL>8{3rW9j%>fF-uui_*`M4Eq2katEexBy1+KrWvz=p31|d|Y+Z3%AQ0f;A7`Cr~P7 zOIZE1HiwIVXznX;s~3PlJ%ue*H(*t;ST4tE#TWKjN zx#C0T5@7R4on7_s5Ld|#k5E$K5lJ4wgEAlIby*nc;-DQyxiCPpmJ84(DJiPHvV z{71F_KDR|sXIcmns9ZFtxl&5u`w+^rw?QPn^P^LN-SAd~ypQ1i^LyZmS8_oVEmI}y zue$Wz6T+Lr`<2;2Z>p=_@8rDu*=j(0o3QWRy4;AJ>5udB$>B@yx+>VxL13}*;^S_z ziQh=}yKwkAA|Zi!4x+sKPi*pBttKPr+&ZL)2cw{fd3-GpXUqba!GBqaHf0I$mx+gG z$xn5DXpdu$D2ElfU7{;PJ1_1$*;2gCU)~N?jOQ~Shk~+Q3LRlMuq}essHW$eD%H?! zcPac9y9;GtPl;^b2fn_*78aIymDih7YHCXQSK}5xT!d1FJSuQzo`o3?j0`foYJh&0 zEzM_sv+G|y65O!O{cT|~z=y_l-d&GUvm47A_x{>@RA4MC+(6ta=@PTRIO!15z3AV| z&Hz-c65!O^;z_75$!}s1pQ*aKR%amxo2MFCBhd&ChX`MQD@QC`txmDq=jvTHq_r5Y z>2;eapASSych3L*#0u*NOqJ)$Qm%VIfk*L8Spg-Ao z4+0dfqsbY#5rwB%mKMXO;3nsx!&@R^z-N7XA*b7kXyXU?HAT|W8+QIsf}{`Bk9n7v z*tM^!%mQ!@{2!Mn&+&wmRPo%zC)--WW}1w4*my~N;Mqo6Na_$OG|vrx)svAGUC}{+ z41tEamV!XPfkNz$GZ};rE^n)cC3S)!y=8W>SO!0A8{(%_(DQZLW@bicQT1iDC=&~u z@Lg#N!U>WGn{Kx8v0oMhArC1?Aj=->#jokam4>7#oMtBHJwkM}6N*w?N2fo`djK^T zNdL!NCQ51-{5kq3n9IQyxl~KDEN9)m)7|`nwFsk%*eQi`3ta&y5+86w?K;SbN*sdF2UjtmP;%%1;Ye+-$DB* z%7sBw`v|PLE>4|le+Q3L>H!f%<-gCXxwbvIvP%fQX|=nd267X`Zoa$OaIQQ89!&KkZktQoHSz)YNx~4;Q=rNWbLf^GPtY$yq|+-I;u0+bwslPgTaHE> zZC;N}ef20*DZ(+Cm!6r<& z?PZUL!;^+Rt2{C6tk7b@)JpD z6)0Ffj7>OpEZCY99N%b)M;^f5EcpLvu3IRNgposoIA|=9S=_G;aZ1Cq&9%S(z6;KU zw6v5GWXIUf_Nf%P>|7CMYh2h7dqB=8(9zMGcL``MuBO-Sm%p;~q7E(Aqkz3gIV$e$ zJ&}wnx~5|#{w_k^V{45w#+O+CfO;9U4mXsNGOCSH(HeSEzl85)z={&45Ur5qnimMBq+yD zIa2Ky-hUD4j}GIpJ&!y4^D`!-ypb#vZjR4@_suKAgcdI^;PL^;Mie#(gjZSWWIn$J zygz0y@ajd{A=rf(NI;ww-k$HYY2-6ORHt76fY3on+Y09Zyh*~#>x5z;tR2l9~;=_6$_4#m$xR3 z>p92NCq)=#{e}lHtt+cx{9Jj?GJe_I!n(dNW~!~^rkqn zZT!5oQX;2d?#AlsZ`l_S4mq-4hXJky7TNm=LK=^hxd6rIh=f46m(PH^18paO!gnw6 zGT%$mbIx9H*n38pXqU8I=+-dp?ah{+>$p6ILc~W9311Y2{v3H6z+JPW*BEcLiJgfa z2d`|+7dmvfZFgh6DM($aJA0G2ncUKypidhc4JTiiPq1~-VDZkz0QG5F<4djZ>q+RF zs_R?(U`PXuICOS&?$p#>yz|PYLkmsYxXS_>gO#1l!th+j`aem`506AK$s5-T9YpnX zl}c)+irC)a>FPsoKQHkM4?f>#nk*=;<8~vo-$T&6H@{nq`S3+VyEmF%QySMzwM$q5 zIjrlpp~b9)VSqdd90S)iGtXBl7;R7rhTU>0Mx2_R!A|I5*(#i*vskJDGPwu@-~#iO z0&tMG@bZ>t`i~P6;9g*y?B*0drB_Jbeqq9av64ujs`LnDy; z9bqy#nfkgmP&OG{w**a%$a8|NfdhCpJ9uW_y2*9A`gikPQX1c^-i5b}xP0pUTDu5T ze#*v_(*HcV6Agq(L#S0aIETNJTw~|n{gIyN5qT3A&n9a5!7qK{Xj z2G^6RsV`9V-R7FFKFjM5a2gD>iee#Els_Kr%4MBMM@MJVV;J&g?xFKAq=@G0ubZ$( z@V7n~sk3ZH=uA6}JkdDtT z{e{Hg3`YyohY5*gW@WKpb;|PVw)$|C3+?+}uR!8g5N^A$rIMfXJj2;F>V;7)A0!{z z%1oPFVmrU6ark;7+|k8^wioJ6&?0J7UZhWRhz*<^h)KN1wUl&J4D8?VnFHA}Nd3~J z{#%iqh8SB9C?XwPc1^&R6mRX!+P04R&W3<&9SHPbtF*LKRWR@|!QdQaXcbx|jC(g( z44!2;V-QWz#sfARNp-r&0P?QZAqUCaVW-yM++{svsew-3`w95T!Uy>B)a;l_6+COQi)85J7YJAYsUQEZ{_qEmL@Y%(7zXMMHDCC4n(hM*Hd3*7@eA;{{m;DOEMCSHgw2v_KhZwNxp*4{2*+G5EFXFj{VxaVN6`a3WUHg@` z{!^h{HY8q4bBx$8l$a(4m<4&_B2&*_ie%=mGr7-LuxjAI@ zPMt&dI<4bNUCBI?<;Q^I_o0}Rp|L?;_LW=MmDd}P89BA~juTXG$8W_I=X5**Q`V+# z_OP_SE?P?WU?05cT1d29n|npoF9IEHz_W*`_z1P02Gs=fEF2sJ=VRY_kAvGQgQ$r> zKnU%T)B;23r%%&TC!|4OrJvbmzA;IAzBdi#75ugTH8b6!xWd@KW5LWAE^8Zb{o<-<3t@sbu%tKqH&G!9A{zG`KW;mev`%)S(?k7uMPQ_B;;R>fJqEM+r?EnGlvNoV?hse8Mqmug-!14AJbDq_%)j~9#wjdL9uR|?l`v*-*O>)$$X#^r z)G8^VVscV*76~d!D1Ce0Uo$H9$JpkDpBZHo3#T5Il`h?LATK>G<18EQYW>}OCeq*V zl7fFYWs<8^hj`e{wdV$*r+PTs%c{t{4=WzSF-aQZq-7IL?IrV|EpN3I{|WN*vYQ}; z6y6&WYlsU*@!(7#_ zjHON>POtIsa9_0bctdLj!{6`4P+c9&4Z7LDz(2z^4vv-?6H?XeG`1oY zh8$&TDs?iq(>|K zELP%zeRy`s1cZxx{<)nMlhiiX7diLD#w97;7V&3B1!w&OIC5f6{~EZzJ_7ZHSqa;z zA%)b>i^;+p3?k7WV8t{ja*Kw%^_`9%*0sUuUVSbZl^M=jzDJBklE8PSLsHNlp)@@o z;yr3eOUp)t4IF;&t&C%cqEP92KL{Ug-uWjDl-a>jK@ycF4$8dq-mm4VUaR?znHveM^~Sbhs~2 z>NL9*pwI(Q1vS)M>Ef2*Ggtn}CrRFypfdwkvHwUEK5g*w#u;e*6hVI>>Y&@Z!n#-tG~t!!eH z*it@0$E?LpO~ZthKXD?sHUkb+lf>Um!!h<&%DF-3@kPLzE%YXnDj2lwmgGMTuGwJ7 z1fG@I;rqfx_K#x9PIpXA;>`_ebKRcYJr zWL)Tfg9&)k)Dj@#D3@A>o${!IZyi&0RLi^0+CU?#Uw@eVdFwe40D8hZYf6s)lR@$K z82KrcdoHEWJz7mmDW=MkavB`T{(SRKcIRkJVHZj`ecy%Lyk6ABc*vUW5 zqMX;x?r@N(MYzX%+BjVjvTN5XPJd=XC{28nOOLX|Wc;Oj;NpqtWJ8)cvs-P$Tu-wY zee}FG51O({HbboZ;ys%m(@C?Sbp*Tf+{U8l=$E(F_ua#PRS#{z}#R^4cLPMF8s*LmA zU7Ck%1AZFUN4I~su8Zb<^zp<81i?fm8adBN=e>c!)$`?vvF$@C$AWip-7wzBXr}Pa z-s-9x@UG>>8`>bdIToJnFpqq5^+k5LT}(lu1jvKd?b4x^(AGlT^Hz708+zEnz<1AY3S79?VmOd5Y;*xA&)DzH#SAkRmD?bzXA-Y#S z;w%F_8v+6}g1->w;X%rflH3+U*hNzIGxYMMFMs0GTIhl*2H#Jg4z`9>IFJ+fx%Yv* zqg{dDg^JWj5>gDH?+w%4GVqpA-6I$X$G#UN*M>eTy%RlnI6&@9*h9hWnTBxUx2~#q zqvH&btz|o4UVP9Zq^6+)J__V?(A{**^LW3#@oL;f7aQrcro`KY*AcnrkF=D1+nGdP zpYx@wZ3t9+v_`*A(P96?V0xg~9+ztJ{&jS_8)3CmqnkY;4Qf8zb+our!Zj&3e_PYU zp5kyU-J|tCp4jrp#eTjE(gh@YZ&2-zzX4rsoMP4D_6eWaJ&_;d6og%*yY+1^%>_W^9!s~BP%=H1%dGVE#7DYw-P|Iay47aF0#-{4 zfmuc>6HIGq(TN&*A=(2CNWK8DPeRBHRUWCIs2&U8Ba+%lSdH=Y9z)b(4IoC2`18-Q z{e0hHN14l?`048v9!Pg2@DDz@)R+nyj`Q^bpfLCkaBg!YZ)E8Gnbv*MDqt}!1=}4p z^!(w0({jYj1$w5H)mP($%TXp9*Jgdoe@g^0&Ea-5MA~PNoDGZ5cdBaMLnhnZC!=A! zkkZwwECCWK>BatT#kh%j;0)fLi)#Cfo|K>OFKAX|9`OWq3X&Q!2!4P&MFSOMUikN? zx6VT4l^1+sj}jy7BP~idhnOxH?p$PMk!^!o>a5jYYv|^cN}k2F-`3=Q{N*V0I%FezTBZ^mgbg0kJpf9zizK#bF+K`MA{F%eKo0t5l>_tN& zA5^Qjh9|Mym*ZVG(i^Gf&`Z}#)i^nn{clna@&d6oWYc(ZUzgQ@R=zCFA0dhAbp^;D z8xaPM7Smx>MINq$8QG+|(D*t){;@1fC}rK`>NI#`!PZdJ2dPcjb{td0&54r*+oy^onSg)4 z;qTN?G?|J%*q6wWoia1|SYNU98(7DP#xlot;Y@V{@bg!Pv8Cg?_u8gB%|)|h%AMBr z)h=Y@WV||&tHIeeY$S~SpGEuu%;y#{NCqY!+6J|h?wEiIcP{hQUnvlpfZx|BP(Z=$ z!(b|407+LX4yE7{4~KjRjHjh}_y~EIN3THk;XqFQ?$UX>Wg=~pt`n@723j=ec;GDd z-bb}BZkhs|nSEQ6<}_^zxWrYx&%Yr!S;+ndKh%qEe4q>Pu;6&OwfB?IKN(NQK)bR= z0Z1D3A714D4~@+u1F2GQVRTC$%e(7b16`KScVoH zwEir|{1}M}H;{p?2LKvxW0nr|E3!Z-!yNuFhH5l^7osmCI1x)EQdgGr|2GQYx^AzSo2fH& z(gW(QfKr#R^X8!QhYvuS9cGdyY3m~c3e!HELq8$Sf1gb30W3$J7^uZlJj?0U4p4pl zv>D-`{_~frd7*FLvli!w&eA>qVgSStX_)3Mw>iy5+Qi7M6VBDZ#?87epIV<996;pT z6)c_<6x`L^O-JdQJ}=#^{#vcoQa?L@pW|eQ93ZCr_sTQZZ{eb7nI0Ik1t2mnA@9;rpRlCFGIckXMJC6cI2tt_JplO) zv~dOj3p;ow?dB}%!`F&k$=?s6jix^C`%jyL==NLJ^`$Dh-iAoCO-SB-NLYh*r_WT9 zNW-5!TGW+ckdXcOXnJ2U^$I6G5y+s)Ug0L5rV1{k`jD!|K(SkvZvitjy0hQg-<;vM zN&Y!=J|^!OdHv5Ia2OdTa|dl^ zE(Np%{fW41*vu>(<>4E+vp)oT+3&xWi9#|}Ql3|lB7CcMsZENr?yl<}GfxG1xkU9? zWj`fCg$13K0oAixX?=kGDUK$|W`Db=8r<@UwY(L5H4Y{pu>BidSGf9$ilpTg@OMtd zX#>uMD1mBZ!=7Z(zP!r9r@pZC6wF62YTQ(xBZNghDiailNp;DIOjAe*QwSB;JnB4v9b#H)pdfweAb;q9P9BOxTZUof2~0$wT+XPv$OO+~1{SYGY+P$>X$s1n}ws z$HU=)C=RGo;yO6Hid=S6Au7{z-bo2&*L*bhHn`c(FCybKq-C8x!*b<@K;HwS`Sv)_ z4P9s}1&0E`hJ4nJ2SGv|Vw7v?F^>m9OS-=N$x^#PQ(3WsONIU>V8d>p- zJFK8QgT`|Xw`1J?xUVYfT_YQwER__I_>}{7*Hr{Cwg_2@y3e#mcmMJE$W@8a1v(-- zy@#jCYjIZiX>?+wZLo;rD1}aoFQiCz7Y=h24wyG?Hyh533f?n3d?Ydd{|V8uZyYsG z?{mRmBR{Tlmhx<}%Q4>89o_L!)ShfBd5(FNq-0uX*)^F)gBdT#zbNoqXA;d0HahFC zi#L=yTSfJdFS3mVHBfgW#>&oOFg32by9Pv?K5Cn~rCpX&ib(M|Xd76QQ=S7UHrvi+ z?hC@}Uru#jW^aBPH-b3D!a{bM4Nq@fKw7cJNc4=+pEv3+v525#5{z#lpUtD?DAXz4 z+0?-96L?2op6Y^VZeFJV$x^g4A4r63Tg0Z9+&OOwfVFrj8AXRXbjtlpw7gq%865N1 zy02o0X%W51g=hg#gC*R{43srK+leT2v6GOg$%nTg1{y=KCn6_|L%Zr?U zlY5PX+B46gl`o^WSOR3jDkx@Ax8Dc<7KcZuVDuek$!oBNlqK-t7w(z&`$Ch6i03=g zNSga)DbJ1h&K3~3mFKC#Ii$QDb1(G@n+h0oI(j+;4FK0x-~wgQpaq-};9(>|R4M%c zLQM$|<(oGH;RFcuCKtHyK6+#Lvyq(GrtM;%${BPM*Eg2WGqbb2^Chd-4FS9AGLi6x zLUdE!GMxE)@n2_{CBycFk>-t{NGPQ==x)BscLq<=)R)>PckTyfjK$8R^CXl6UkOzs-&%)IaWg*0r2kJ=EYv8{nX0V=pQObz*&&ThtOc&&u+z)XBX><70&T zZ85%3!`lz^OgY6*uCVgzq(lS+b*1DMf4zL|VnM*)-@c!;f5Qe<7C&;!LcuZK=X6~o z#$5oP2B|Tq_xV{N{uv})<(m&vGNkZs9?3i0TtxHKRk92S+k!M@z?tSbp*lLcV39A- zH5a5LkBdIHD|%Qw=0T5CWNN$e96>iBQO^#~H51R>N?tEuKK?dxiwZPp0KpsHNCY{{ z-Sq7CrZk`8ht2~>VghJi>nAQ9x5jF|E4T+2vI=`#Y$yJjXk_<&YPRc9TQVj1>tll&Mtqe z4ERDB;I5AS#CO~an!2L>YuhT$v|WIitKpXOX^S?e1vI`!A@t8RYnb88VuBr@w8se7 zRb(kPVKM%vPjD|tkx9C5$clzy2f@OZQ&UqY?*O*>>&lY^GuxIJ8+&dz0Cdj*ts+9l z&5_^b*@7tr#SJ3zB5FQ8kP@)ml$FIb8j7KBDVn(k5#OF8nXv%W52 zCF>ITdv}?u{F^Z6Y}&}gbn5W)h@3%POa#QK+`CNsTM@-$HT2Lj;MGqBiI~ngm+0Z2)He?|-<%rn1c z(nl4^DhGI%Zs|+Vk|AIRjRoePuaNL@_sUJd{^yBMhC1?X0duYnKkQ8ID}A6bHwkbn zqoaVsjF;#)|KA@u_0N^{g)sb>ZGz!$-r~}WKX`rzjABmJTxZ%U8G3OV&m3~b9cPOsUj`3@ z9YZrYD^hrPyuX{!(sob|Y5@tW!_gEQ2>1!#fTMZ%zlhS#8yyk+EN9xov)liSH8OdK zgp4#B35MM_{zA@Uc>q%(kmtK|-pPc0Pef1AYM|;b9e}YSU6$^E7jkqx9M<{tIy#DC zhBgsNd#ab3>!|)8Td(saT%Rtyv#@^lny-4w^VW?Kn*T-|Hv#Mk(e4((6|^D+TKF1P zmYMWMPAaRP>w5ld-~==;gx9M3yT>F+8iGXsD^U@F9G?Iw>l3aikIm zEwcwLxeZ@OA|arIA`zth(ah&R3MuBV4>LKx^ZF+z<}kvqxQ1;_i@NQYgoLQSuC_Z6 zRM#6%lKpeLBmM1CC|0f``Oz(%l7BGL_xloV1rVsKh&a%N^` zybWCpVL8`u-y0w1ER6^Eq__Y3XyK6Z;tP^)rx7t7r@fCkugHAH;sN#lFYy2GW8YUB z!^a_4+y0aB3A*~eTB3#V^pU>^dVg#Ri^!;T9eu<^R3w@9%2A{1OUtWjg6b`dxsEHP*6}+zctH{;jjT!G-pl7W3Dx z0_1lMqE5$!cFFP0-TBPFr4Rye)mPZa-iIl#wu>turj_&ed;b2WA{$oW&!4;->so>v z$8*BLz&()f@wAbOIp2NRUIImeB&_xc9WtPnhTuBcY&b{!z;)Y@Sqqe@A;ZqO@*=xtki*sW zATcRhsa0ev8iZlqV_Is+3?W1R|6G4u`=!!!kFJA|_dyGId~oP7pv;_0ppbyic!uWZ zwv{D?WeeZp5k$eD`N8}<(~xr9vsJxPK2H;h2ia9a$>{Sgb9lAfu$?N?=oKfKrf z{x$#5c{s|18Bw#3_Q@>uhR_ z7CHu3ckLE?fQG*jY~L?Vb2Uzn=4xBWfsdK7;Bjx#MkTGq< zS^9c=bx@1$hK9>?50?#=8NM5GLUssyKE!~Hw6IZJJjt_l5zGC5E(}Y^|Hs~2M^%|c zf8*D2)NvFM5NU7#MM)8ml5hkO5g0@SL_k1FO1fioln#-Qya>`IB^^p!y1S(tF5Ue0 zLnw~({o`HV^{(GP?^z3OJ+aR@`|Pv#XU78$b)*SyAZ3Oj*`DXVy!I8%s`VvOE}N|P z4+SwuTzhl%y=fLEj!;F2G(-aLAkTud?o*cncr(om`t)fTt|5VWCU42lU|5r@0P&?m z8+)Xzj7HDqMex5oj^vBoo)6T4tNO7am|J@m*MEwF5!MCo$vqkciXf#D%1HYe!-hwq zbyU!M9^;;t`)5!pgewt(E|rqEkW}yp%7fJ8Ec+PO$w2gid+_AS#!|8fWy%eoHhl2e zmmYr|@Y;=3J?vm(-@Eqi|9YEma)1oAL{!$* za=rBp5fIK0N%;ko;*J8_I9m z@%P(4dZGDb_iKkRq=XvS$a1yvigH@{r%|S&Vom*05mQMG6Tk;Ztz(E->%5}`wayhS zww9O*Sil{nscaef=8Si`e(CRf0s9`MC75Y&Q!}K95&id=9_Y%y`aY0acctZE60LpA^&RWe@$8~@1cEK{$-&S;lpkauooYd(+Mj;G1t5e zioGGpO#u7$YzFmRhP1jFdhZV)tHvWZd$0O&s!TipI0KTFN;$j3z|_9IZgGPW@#;g2 zF^BicEhMN7AZRfXFkJw{>V;&OpIX=&=rFtA-t_Oyh__mt(YsO%@l7@J!=RyYO%J&G z28ZgK;|SjtnS8Chbr-TDrjV_e-$)24x(M1FjV0hIJR2?yjH4x`m`QIkgLI`aF@RxO zbnJI>Q}Sk!g5ASz?;%Zqo(JjLPc2OSfQCOVI{h1)Y78&b&7kY@RNj z67!h^i1CqxXx;YKuenM#Q>?q1GUNv3Y-$RyE%Q@)p$&%A#$}P3gy4dJ($Yw5OBKnW zBu~Xb`QpPj4;%h|U#K&V>{VCPdRz#R6&{1<0G6-fimP(@u$klL6x0alS#uP)%s@vs zq`C8sJ53`NoDgc3(sld_km^HH_4Whe?Sfp;vUw%jb#037%sRPHT0(>F7|5BBt1Pdq z(3W|*SN!KN4X81>Z$x~B+J*X+=fsdOdGIZ=HUH*7i)>Ozy)1y$Z<&p(zLjXK+nL=# zYE!4O?G}_b5ZK8}$pb)GoOkwynx*ndK#P&8WLN#ce*nUF8|z;P*`vf2Z$Ffx?e)0_ zA>RugOYs8@yB~fzNc{gTU{I1G=|pr~s3{vYX z_1LKgT;@q&>C&O=+6EZ?t0Ey?gI#0(DdJpKNow6lEEhA#5k*SK^>92wavwbUc6w(> z`_drhm#K#eoJE6@{2h?^{8PJdHF2fmuidZ16v4kJ^YXSw^Td}g4r~AwhovzWK86`P z9&}{YrE0nrVjq$CdwAf6_T>5!ByP#W*8ULu%Akq-g~V8pkwJncA%tta%i@as5Y52E zAjZvS9oJU$H;c99)kbLn|`_5n4NV327 zyV$6lN3O6`!HGetd#v9PiCX(3LPQ6GWFatyffLdlk*uIub4N!V@SDA3_*n%*{aXIb zQo%x479xcGu8rjF6hy-FejT_oL_D80jG`4P-(5A0gRSJLy#DH2Oy$R>QK>rRFobF$Zx);-c!2zeya%vV^E zjQ{%(#QbpW^UEWBR0L%4Z)>@VAOCUa^!>L*)cZ=QgC6n-T}Z$bBSE4&chltgGgl2) zp&I6Wfb`#gkIw#f6$jJ(9UrA2F0f+*GXI3lPUG5wDLkSDsgP2Wq0&O{tJ_OHx1|Vn z3@n=CWJh)gsmPK`vTFM_==iVq&OG~ewSzZdzQ!HfOs55PZ=1y5Pg zg196YD3o1w=WrFoeE2!c3LvEtIp{D*SS8Xfuy-@dzHM8TM>beO}x#pjkX(LWcacRk20`2Zd zA4Ml=*f1RcCs!S_ZIHuI_0LR1#an2S3y=T~K>|B$v_Qu}(#ywJT`h~n%t2OvA{Bz? zZUvIAo;C-s=E-={ijcClKeoUt9I;ibeYLw-!lSr?-licA zaa)RS-E-aFMZTQ{b-1nG#g5apAhXxk+?=KPK&&{0_nH$y|8#7$qr6LXwyUQc6NHv-1bY4HM2tHxP*lL`^xa6lPi+R*rf0K26&T(?;?b7fITIUQEe;kd-vs=4>zTT_4Q2->=#g#aX`cp81 z2ef}a(7X=rj}km(I&&^Lw4)~|Pk&{`2ztAV_X-9X&OM2onB;>isG`12@Drk+dhpBD z=`3e)C28fp7>LrlwF^q>-BeVJSf18dpDfFKj zbYKoP3;fbE0|{A7Ol^N3_5A}uQyf}jl9HqpK21rhMPyd!NCt5U!-RciIY5S1rGDb1 zUoT&IpC-YpayKohCvEiO8S)sPzFAx&2DnxFB~w$J&K%R^8=+Am0oS~xIn=BFIh($} z5>e!*zKzxaUFU<@&0aLVl@2tWhI!7=>pIfX#(6v&G03KnM+g}xL&ilXgD0jf!J3(G z=^mulzxY-JqyF4aL(T{ZkvUJx0%{7j%ilcG>z0e-vp!Qbsn<)e2*XzY>A}NRt-&(B z&dlULp+>R%iW|v|d-=vjFTY=t{HG4fHD`*1CUFfu2B)cp;_Qmpi8BwL4VK-f;QA}} z^>IlrGU(rhcF5(Wr}v1`T-d)^`uU&wL43`w{Wk#rw+0j20{LneeFFoJw=}bB z&Gr_%I6Y^$)|lw@oBx;MorPJa-!i*ru0nS&WWcss9QWTbQYkt^-YiWg3`Q)nT`i|un`@t2v zp08eCzI*}SCpNxGZBu!tYjTN1K<)W#LC)6~RYPXj#e<}LExpxR zrXR2Gpb~Kc*O!6u-j3A@PD^tOY1PukMNf3re%v($r7B$rz{DpqObpF&Ly;jgYziOGQuyBp>d*y>_K1s6R3a! zPZhWvt>brlk?Oa>T6$k@ zn1MGE^&7`*sYq!v>!xZB5r$PqCNpp(+cmJu4Gm* zWp-W6tcrvn`$*c0S1zWwszyXiCmraSzg_!@10J!$;fq7(;OQsriU$%DuIF&(^MQf% zt;>hsIJ6!Z+lRmX_TGWzr)~AyZ}4XB;!lJe{<+}LBp&{L?|qT~VVQI_F+Ar_CG?7Q zAtlr({8RVOu~P?w`t4MQ>o33WQuQ-=g>y%Jskk@ul_jC@o0vpS`RfBc;@c_UaDEO> z!T-61Wq>RCfBv~&>?c`v_+T3-|8)5CkMIBQj^0n}_wdbE@qgOy4*#qSI?E2!H9FIj zQ?T%AC%}6Bs{4B}f;ZGozx_`CL`2u{ZHzMqU(k>)->9y4TF_81lO`vbWN5zG%8ej# zgHI)L__YeOluSJ?_T3Qkz$Csi@X&a7?s_HiD)#5tCC zz_{N@&^o|ezkda)h5LVuro;8u0iACoqK&~M8M~RsdH4i)@1WLa2!+HR$hChB@EaLn z1Z2zOJVid|W&Rf{-&Og&lLYI`y3epdTDDuMMd%_gBY!vN<0;j}L4iTl>wi}&W7KT!Weuz^3LkloM zZcTXZHac#?tZu3|gMn8ah7GDj znec=}UWY4wvTjR)8$5bUzGb~qasS`Q5)8+rN|egcE-0AyOxJB|V?{F-2UQQHsS@>8 z25+4RK5J=d`JdFoeezzaL^(N8C}e89KZ&Yu((C(_*yD*yRgc{`Fx3wF95%{OZu<9Q zQnO!={?6dX;)zFx4t|A@hZHDR;55)*seW^sAL&g8o668XT2Y?J-Z`;Ua-99#lk zpR;o(IR;eTy*p5H^QGFfpE#A3#&D29*+qY4%C)sMc}VzNq^9 zE_nodO&%twNQ&Nf@|W!EIuna#0(Nu#pXCZQ#Qi!^D87by&R(sR!O~a4hP~sO8ZZ(+ zHZM`k*3~9;O?2DWfZ-}XR~kLgfLowa$W(OG?;1{Fpp|LLiyqb4)&MmNIYKep7bSyUR8RaLHHb)gM20k3a4 zs`jSUX~g28>ZPX=lRf=MYIIiaX&V{_o3HyY{shfkn}*X}oU$O?kmtt2gcwU{?Q~Zf zSPWxVLIc_80!hib_>4b)NDEK+Kr8mmVAv@EFF; z&Dwq`zFkqF>uZOB-AJL3l#0svNBcY4wL$1tF+B>cwNCF;NL_!>8R`lQf1K zQztt4;Cb<+xZTE*kHJUDI^rXp+I$98{-HSHUeI;ju{m9NQEi*85f+X2h|N(igIjCO zHL={1Kf4q+AD8v4)0g`Pr!zUzX|{X}TG870#&Y9AigDeHSzX4bPi0%?eH77X!`s2u zUtdW*dgvGV8YSr6IBt@+)vADP4(3kLG~d|Sv2RB!8B3pz84voZ0e2HLZ=Q~K?aUWh zwzfsc-)|1)cZYKXC8ecW84B#0h&)#}!;hUB!1Qe>vQ*}*7zS@rMbB=@i9#c(W}xt>7Luyzf*9EF1|?%P^-s-@zwxJqe1^hPf4 zxk@mHt(6-&2fd4n%e8KN)R>D24+ZZh1J6iTB8*OQ9zGKjlgQ@ON!ty~4m^24^W1rh zQ-{=>-P>U3s!d%et#Ch z?Bf?wQc~I+=in5ESDV>hUY;dgV`Jll#|1YYGVh8Q)~D?sW5%24;&h&co6q((Yed~cpTkW!OV1awx?M`LH0!Vo{WqX(}fY_qrb7^G8M7F#)tq0`b^i3 z7+#0lm^0&1(|*aM0@iuy*wsSwzShW5g-4H6djdI9^lJiFY!g!B=lFn{Xz z@UXB8^YimL3M42GG8oE+#%}T&cxi4v2gMW{n%m!vQQSIl+GV%Lumd@d{A;g3@x4`v zqL~}^RHOoVhfOx$q7GDegkP1I9PbMC_ez}@a2!qOBg~PRfhUi zun~pZeb}LRmNKTy9j@!M-Jz3rQGzd^ZvztxEY5|SLz>}|GNwuUzVYu@;ePTi_AMNy zI^v_vx|LpmZ8|aQjOI6yWWUZaoO2#kFCHDr&Qq|~kzArpgBi;C_qz7F^*SIYCOwOG zd#W>Nu=5m)D@MtRpVHn^pYc)ljkXMwgG3B-vYTt&4Lark9;PVCcjU1T=-Uvh>2Px( zXRB@&Kf1B#UZ;e`u1*nBc{1gil@KIXyK=J>o=wirV1y-`GG$~sW5s`~sAD%zvt87J8NYL9&ozjMO-Sm@IFV=0X2V;rQIxE$}qrpVJ z!-VqBezke`KuPHw5uu2oipn{{^TNrEjl`WhD>U~Io>RIQnVt0S1xBuZnoS*cUKfJ( zWl!WU4I^1?O3{BS;ZY_}sMRyGT+Quyn1~_RxnYC*SMy?uef)2w4-Of-@?T1P`hS@= z^=02p+HV&ZB>OLATJJwEdZpa-&?eK%5+Z>qIC?_Wdb+l~Ku1$IzK76yVlq57J9|1g zN=skA))W*+wfjo+gu=&ONy+_n7BU*89^S{_(pkT~!*3gIFWxsMEkgl%OLo#O4+y?K ztk0FFfVd?4r0*eI~?~ih0*pYsmBk_5s0AiH9Z8FF1b;Xl?n?VkV$k9jO@WJE1r9;4cX#Q{LN*0 z3TnMN$z|~dd6c{>Q?;gmN8mTsw-d9lD3T+8!mnN#c8*D_R>nq`k_=uFqW7&dMQnPg z^Y!`A)CiuR;(dO>ZevIdTg|XQ6C$xIJ4l+_o6jW|V6F1j%O+WM>-)3TXsBG@I)=QP ze6)KF@;?sGBuO*u&vi@|S7xjSQrgY?1rhP#r9PRd>te98YRx*m$TmQbmgE%YQu$bR zS1^VhJ#6q^d)l&|VTdU%bTtj)97aS3_jQAY7jmm3jjLm?{7XtT>zrO}ZtkDkf9vqf z-I0TRppT!Mm(psv;<4-zRM-jb=K8bde9M33WofBwX4cuT##J&PBM;31_pp_E;U;Wd zGocI5Z(LvL5HddX`+cbg4~UN)i!BEw@Buvwh&%lJqbP?yvFIkSoFX!oR_r;hUl&nR zGge)j%+&YTSxBQQX%ko(j){x8$GE#<9G?C_-5sDVm(u$3NVRnmWDTvw#w0Mh4-9Lyx3SY*Sop^oO5LgZy?zv3@L;JaM{Gu& zJ$Ib@UfIXR%ZG;#A2@AL)|3CNWFA*$Q{DM4h;{hhy8&<^}M+| zyrptuA%v7PP_-`fsFZA`z!~zf?mJC>Azg!h=FZKa(4pg}V_X^{B%P!sNXU;K ze;};c+o;!-L8HGmjvM|-U$Ts6@7mml>Ce&b4L^n*5@R99u6_Bk$%QSkV>KE=sez{p z;{{_y%pPOzM#0NP&miWxnmwJtJ1DZUNe^QFc-O9oc>dvcqkU-Ng0^d)68;IYGX=9t zjRTGExQzZhgMjTQOzPGN+!6x~0TUt3g?Z}rm1LJAN8_k{=eNL7<{?vB`pU3T^k{g& zwxDje9GSa&4F&%~YiA3qJ@yON=ptKc{cbS_hvkFG_23rkRl?7(HZPoA3Uuk+?T$l9 z&q|3}iuum=nY!U&VK-vd3qUfW;yQ$erKU38_GI?R?CU*$0{6O^#dZ>g(#2V=Ojtg4 z#cg+tvxgLzzKcAQhCp|+fdJVNa|>or$s~9xkTJ%_gk2E0?LmH4U0s+WG_kLcWyX3w zg>es_599k`RKqedIP|T@3c!Y#4&B(gEWHyGbG7nU)bqUcEv}}b%M1)Nb5l($g~U3X zdewg-*gpssw?oK*1G9zxXEBk*V++NvmssIU!J*OUfe&xjMQ+}-%N=bTU&O<4*qu+W zALp~bVhv0nX<(CnsaF-bE}-S{F!sI~g|0Au>@F!jGYm<)vSu@5wB)N9*Y@!=mn zTs@_SLU9EG>z8`{!O_rQH_9MJB*GI?D{%!m6x9ov6}xYce}Z%$n#RvK2HcO$Bfc6& zk6310ojyM2gvG^$b2ZIcrkz{J+BEm~$l0fdK&~(XAoje1nXbXgJsBDK5BIk@#9;^@ z&-Ui?+-PdJu;+6P_=;Zr4o8@LsS-PHYB6%BpqvurFsP8MR4OI+u5Ttl)~|pvF)PEqUhzi|&kd|A(+^XC8 zF7h^V5fr(`A!_@7la`S=ANxSb4_3x=_Q{@HSw~H%w(k9EPkqUIdzc4k z($&oMV1&%-poqFUVxx=Xrlt;DzO1!VW<oGXQXp|G1Z4{Pe2pfY{yN)4-$Ypmq~x z62>&cT4OSaVjtl6v5y}0%Zk&uY_M+55fVN{?t^(TFtFSwV75qk4!MED(7{fKeB%1E zi)S@_H9Y(a$m%KtXz@4(i+I}3#(FwQOHZ$6AA6xbtXz<%c)Sj9aXppVjL;-3QhZOm zrX~f(OiT~CCd%os)AV@>52ePl9oLB?sQ!G9r`>50EAMxYqOCf_JwJmhKy1_q_>`bSX? zza8FKMLvLnQ_MzTdlR;98!r#X03JJ*UCmn1=!cH|T{aSRrfz5$8KSTS9xJMj_GYZL z)Goc=hatlL-+&4ei(TzZ@y*?g9sbnpY;G~&TWCM@--|dG1h9!ar}yq}e4;m#PVK%! z(N5DeB{})E`mN-LqATle9!9zPwGOd2b{-Z42S5LxA)^OpeShsdH?&WyVB_*s7Xecu)2ub0fG<_ca7zcvLEr{* zJUPd~TwsD7NBF+)3Wf^_WX9hM48WmWk3Jl1Rp0LfeT_cMc?ZAzuXX7ED~kF5yXe9E ze0%-xi3$QBYwwUdo&UTc7%&bQ9g3hjfvhBD;Z0f#~jm@rT>EHe*I_;0iF|8eiZ_7`u>w=}TkF5NKet7!qjB1@BmY0{C(>SfhS5H4nD_@u^sg5w&K0lYdK3_H zG(@MGFUF2ha1gdgJ(dIeTUhGBU&O-4gx~lRH8gjVi`R%7hGCyHQ?-+sZmg7f< za$)=ZT&7mNKH?2rit;5~2G-J7rL3w&^~8n#D@8mPJo@MtGmC-0IZM~W$+`UcP zfpRatZ=ZNUzjGr*C0QyFY6DJK!^SWb)`UK<%gl^C1EUMB^AR6nxS$HKnxJVR?v1oa zGlhiC)a!mpij>L8iszS3EMJrn7<4)13g;TK8kS@cb8A_go?*LuKeicsT_lnBz3#U{k z-iflRFOIXStX`QV#jX73CdX0LziJ$~%s1s50`=WF6xuMZRYWD5!>3eN3Ub_fdkBxM z9Wz{RuP|JG$ELbD#|jhnE+yCHcUM(NH7SiDkZ@tB&Es08=%#XgScqrrpMOrQmAS4x zKg1N%R^Z>TX|OquMh2TCKZ0*9c5}5*c?}aYBNLFqyFKr?!)Dgnrop&ZJc;YmVdd39 z4FN5vZW!s_FG&wHo zX=AqGS8cZNI9Xu{9v}Z@7m~r~GB>QWT2oRYc2%dY%vem><#p8S;Kd3*`L`@iR03w! zwKD?NQ$ubZ`>{4A{`>Yo|GTu+>5GORzxHn^u`n^aJJZk&h3#U8L#?0qcn6Y3XFThw zH=j~l%1UH&olmghd#I=M_D=7cckJ`cT(iw-1XUYL#w!>&7Qf0mnx8O#x6dSlQMUn| zDyIN_G*b18b9Bi+1d`4arnv)OWka2!mC-~sOf~Y;QjZ?sQ}JyyW-Yp%iiioj8gHJd z`5gT>wj-de6jPUdW5)LDSBr@yBI=OZX$zUCdt}zPHzxx6$_j367#r;*h!PDADeZEd z1I>Y2&NaelX)W43)3a63rbBN<2Ff!E)t|*NnxQ%9CPgsV{8cR{#1~!Z$)da+yIRJw z!wrf$zE)d-(nWRbD|yaKewijc^A?*Kngmt63BaEG{L}L=L&rVk#_?T)DcLK&IL{bZVeAdd7pZHL=_@ zvV@TEeCexban}>db~h%?J;_Z}gKfSz%NOpc6k%*uwVBG_(E`-92@y{~7D&%r@;3dm z#v$t~6fyU1c~e)L$86;!3aeLWw~df|acH?eK#)wHbf7xCZ{LQnEI2U)ILzVY|>U$SNi zvANkgyQd0|G5)ZWgWEIA&AYdo^PPtkudU?~bDBI*wWNAFF(%47?ZZY;mAe&dt=87t z<2+0_L{w5kq(or9P$A%1;LG7WOeuCLnCp7MLWe;~3ErTQVr0{O%h)W{%2MnKr#;8< z2P;*kAwo-uan5WK{7muY50~QH(#q~tPK4|U6~!N{2@je&W?RHPz?noATKV;IVVP zR9jxTkA?Ldu=y?#9&Dx?lY>N(-M(_YuLzd>jZB^^)UO7lqMxXc?$g zx95lK61L(u%63*u(83_ys4X$!3uR~uG}lVpV`@!(^%<_vdo0ie zzir@^Amw6|;8zj4J-au*cf1cFCMYh6Y2I`JJD!c&lKCjlAbjcD=-xy(IFsP*?a;t` z@10i1gL&2Z-f#8PiVjB(6xvO>HWcO<{F3M)?yF9SrIWS0zU!*G$ncClZcs95Q+G&M zDJkBh>*CwmI<4)w^NZUgecTK-MVxoIobZ_$NYV!E~4CDx{ zac3qM(`*@Zb{X%3h!AkQl3QD^QsA9d(@|S?co5uuYI%y-u0l>^Tg}U`G}VpmInO&` zCfu`~-_YJo>|P@-^-lRLqSSyGwxzccL09$~{#jE*%=$ztnCpq$gQd9gyLBt;jq045 zn=>J%87WVvgHmjo;y}USGi#nk_82W)eHZU91D6??-H+sNl=kz#RNeg8z^dOqHYRi5 zFNHt)GzFooLr?Xj9wGjV*!k#WZ`HjvC;)&gnCFc)XK3gP)>jL}_&p&8O7I6~6*v zw#41BUs7dNdxMfog2)~U^E6V~eagN<8Wg13_jxNNLceW;pFg3mpG&VKi)(PGNp-P* z%1u-eB>6p3%V%ZtLN70ig+kY*K>$f+y8+Jwjvm76L9*}D^p3OI~6qCAXG zkl~i%QspvjkG!>~jLmzHxe( z5{U=n$>h`HSJ)>vhI_9Lxy4`e&bMr9UByoE4kn5ln2)bTjYPf6of@`K>0mJ2{>K>M zE|124$_mdgFkW^GV$R|zFkZ2z4GhvFxE+jtG;X7GcjvE`j2swf(xmm8iC=sPg;pW%O0Zn5&LIra=&K%=*k-7qQ&}|9o zY=LTQVwe8-{N*OzNE(Vd#sDJwg(`aw(=N_S^)o$}f-UX_n+;@@7^hwF^>>kfTPMkG z4Et9@ZXQp=UJ{Oj?hmkykWfi7dP@*7L?Z9X|e zfsNO+_rLS7uQG78+$X^KX?`0Utj5B^1!dLZ+8PoV?U!PwA9iac2I2ZU zy+TGhmGOg(6-2b&OA={B`~*8|b1dQSV_6%z5mkxGe#;=mXkkLgn1(t@U?;*^Q=`i= zI+UXHRmEmLF&-MfR3;y)@Er zW;NFNsXOsi#@o33SKcu0@`Qu#_be&+V)HXRr~*+8?=j9so#Lm2>F1wQd-?2m37zI+ z-*!dMy!8ip8QP}Q^23q&s%2SEk3Z`jZ;(a1AeuF{yOsymroQdO%xV{J0a=il-t_(3 zux$qmd<_<|PV7s$Vz)S^=d5ApwdHuGq;PZD(b?UC!mQ%M0)9=^EBUvzl9x1%u5s@Y zhRQzdN<>-sTaWOcBQw*zOB{u77aKD64^35FDW9WB1OHT+ns%JCUoNowLBgk zo1_4z3&Dh0yLW~`8AV;Uzm|r1Vs8$=(xa4*5PrsIX7s>MhPE{_JCfUOt~{}!xiMHy z!}?RRzH8r&9l`K`w-P){w;an;6H~Hd#p-ZocrTaXQZ*&!GE`L#PNis?jCYj%gGt>Z zH0Os*k~wBTGO=4C`tBqD95*V%A*1k@DCk#AR^%{!h^Uy(L!6oEB`Z{G>Z-Oh)Xbq4 z`l>*$HSUz_EZ?FlIFp=5MjEpR>+Z78#+I^_!QevfSf*dZ}tADikZw77`DqH0LY-P2&be;i3PtiUn@WgGUC zyvf=Pt04IOP@8wD(%rpVDtp225YOt(6U1rbvp!xfFe;4>zgl>qzy@AF zhFyKrjR>JxB^$;!3B^$!{Co|099^xLZgm#AzyO_ScVZ$iH=T!TtQUM^1U_=6gpLCwZ=o(MtBk1t@e!yci*#=VIu>Sg^x_#L+N*3Bmc^MOlmzl1(vqs#; zl#VK%J9cc_^vam_r`c{iPd;wm>jpje5aPnB(j9BK9H1$zqB1IS!J)e2aW0b`+sfyx zwJ#vu$$IVYP;=wqtrX1trQ4Zt5t;8JEnDFRGUBS1prn+-kkR?INkbygwUh*=j4oBM z$$|7zu_~f6aiYf|yPPuEagpVcUmHbT9zRP`fEl=%&YMnTyEM+fGph^;SvL%Bx7Tu; z8Ax{LK7}4{G#0G;_^hT2JO4sfb$UHRN>PzQnob-n4m3H0=w>G!7yR>4U{Hh|#zTwi z`2}j~yA1Tr7bfP6v8j`fj(!p_`!c%Aly8&(h+_HwhGX1|F$-yScC zA)!N`2UW>;lHPubRkNdkFMbP!l)bD5%Qyfq@=2omA()Ux9Qk+X1a&W z`jftUWr1x(s{Ic6C-8eZRNpz|^AR*h7{ksC!!kg&v!TFhzI|$zRGmk6s|?3*_UOuR z7{%PpGvqhU3gmB%?*0I^Rtzyc=4Hw|#he2bqoLbHY=X ztKO8A0s8RT|ohY=B^Q`0bkQLxmSARccRa?{# z63b*f`|Flt$-B=qo@2Vg+Lpn5%Wlj)3jm9lj&olyf0(F5xHF$`?{2U&$uvs_WcF6E zl!={Esx@LmT~irdUqVP^?CB&m?aIWIsaJu!a+}AjZMwn^*&@ol4mkisq7?BCJVcDd{o@?#`c{9HVFUt zarE@#BCM83Pg2$b;2U77dri_~CjorXvo?E5Ydus%Ku{G2;Q95LZf`jyNy7n$_s;4W zQ3`6qBQ1!8Q3!g7@s;+jsFWPW%-OwEYw^pd_|>dwogzqe?X?W6*;qx0of*Ips-;nx zyf@4nO2(y{U$Mr$baxy8{^H#t_acjbnC!AaWjl8Z^R8Ft^S~=)@v3JLq5_&BFcJr< zi&|fTVOil{7QC@OHE7r*(^jU*Z)Urg6jv*86B(Pc-(cP7oID;Rs>$K>#MFf*71JeC z!~UYbAv&Sz32*-$-CnC9nv2H+!!#|QVY|7En@iqtsXngdVN}e#L1{nT;WmsLH;$HT zO~qj#sG1O6mt7KN)Y%ACGz2w6)v_l=V{%<+VO?fvoVEBK9^S6tSBYX15qAS~HN{%F z$1xPK!3La1&0^aY01AUn<}5OL@r6)4?=RJ)Isl4L_Pb+$?r2weQCyI*#7`@8cCKK}qgH&VvdnE9-M zb>5&Wcj`Trt;&umRx0M0S$b}8pf-EsTH*(k3s#b`)Asq1RT1}4&n?2VTZxj~?Kg&T zRn2=scVoRAXdWKM+^L=-q}NY5s=+!WRr{rPbWX5|#!~=a_OX$0uz9W9Wk$woQzkC` zYQ<%vVD4wC_egB5T4x@^E^DDbzUkK65PhxVj}Qve4Cj%ha{zidt50_*qvamrFHgn0 zs%#yn^Y$GYy>dmeaQjaio6cdW2ld%IbqNzPB%^M8G$YK`YqnI#UgSn$WaPhIEx)Sk zAA0nfX3K<(;Z6iD5OhJx@kHQ^#aw9Cc%0548&xj9m8{Gt1jj;J?V+H7`Uv8uzwi_b z5)9Q!j&9Q5#-$_yL+hGdTkp}0foNkpU#zv2ug}H6OzXZ-p#>`!2xKZroxq(EXJj~u zpznS%e*HiuSoN-JfM@n2il@2#ECi`K z4=D`3H+MLBwNR2IzJhoxl#Hn`^)OBBo`|{BR3uzD6TlRRf<`arh_IL zivjzWX#9@(xcmj~;{mAhV@Hu_19F^020XXA*U3BHe_tw3l9grl$Tr9$XDgGeX{T85 zXK`9%IIqFD6XH!y@$8xYUB-AiQ7hdTP>UP#X6~j+Hqty4mCx0?m6tI-P0VNUG#Z_6 zGJg!zTe~&K9XmvHJ!oIMnRd$^2Rr3Wgvc)Pm-kSMzwR#Kv5LbqsCb<$r#&j}#aC!E z&&jGi6x$I0fe}0P66eI=sAr$A#f;;XnJ-1vj@r*yt4(N;=xrDUTE_tI?Z+3jm%nJ{ zvR9k5z7sXXu&vzQ`r8&DQX(R>oxcAJ8f;{)`sbk6|I(x8b)z4?wBU5JO- z=y)1-@|r>S#|9D-br+}0fUu|BlJtNPsl8)&DY7YB--`r*S1lzTt5!Pt3Up>(-ctct zQLEv^Ht=WgfnAy-T?bEuEEA5daq6qFXN+>=;ah*$YBIhJD$O*gG;JhLf9cnH5(c4= z4x!)O&K+q6lIiIMJGlv?(en{GZ4ERFd<0jQ#+mJp-GNj;O|6N7Lp* zQ=O8{x|>CRBsZ(h{F-8p^>_|pigueHGv6tb(3_V~9=G?Vs0wp{| zCbw_JN?dq0%d*vdHHTfAXR$Vq@r$z6MS>)8jZwX>4|WG^y22r~vkyke$#KVkB5x38aPd_%86ZT~2&D9LUieqdL)^C-*5AK2+04)CjSN~q(ojTjTx^{}( zr_vM$<-v;M?k**NAD^(a zG$lEO)r{hv*;B+xLrs1EAo2kbcVyd`KKlp}&ud4>5r5`tOTKxj0abxOn@kuc=gF6J z#77p~%?Dz~@bf>~BvpM$rKVeXNogs2vP&_$%HhW;Z(LTT}(`UllZJL{*Aa!b1DW2!84J&2}i;0OP>7WE_ zeb1c}x>@O81xwtEv9Re|997PAsjPCP=`jZ(4i3)Jb#XEy#iLfiEQ)5vK9HE0eoNa> z+h#m9h|RCibj712Rf2?v9_V;#-BVkVx-ProoJzhE$fH|Qq~bg>eP?dLM-)Lhng_B; z^3?!N+(p*%k9vqO^eOp5dSX2d1cwS+N=X4tkhSRcLkNS37Wj13z#p8QgolSW=;-MT z$WPs!<%vWcP|>72c#p4;_<&-aV%Akwk_x^lV$(08h+;kVxnc>N?#@fR*Dw0{Ya>8q zph6&fp+P*s)A2X3BW!en(? zYfVKxM0dQM`qhGSz9f`Y_XH~250Vm;2OAc)A!yGb;!qlRSQqmEBpwEFTA>dA{ih{X;q=`uk_|M^tk z(TP$Hkn26lQsdEa3hfM5i(!j=8h%9{Y+BgPE-~=qGdT|l3+2tXhG%V7yW&^nT6Gep z%uQbeh3(hmL?zOuGI3ExgOTykGDO(~)F}tT2zKqk!Hi7*OMd?1fGCkEXAd+1Hl7a+Gs+N7r$k>^GJROUNK4#uhf3)&%9C$-A?S(NU6{rT*K{1Jqdfbgp@6GF7&K znO-|sp|khp{vys@o^|DOJR_`wyTPUf!{I^k-81JP6ms?XUz=O1` zs+N#Y_rjNA!*$U?HLb$WJ+(~qm)&-NKL_o5wtKY1GtGEesMl1YfDcRE45ig(QvC_4 zsxyS+`<%cFa=E-tlGXtB?tz(XT;Z+1^PPuG%Mg6!sP&2%qd`q8PKu_zt*T|m;=ued z!{Rk6P&Npihic?k?@@CLV#+)zhz2npuEPwnB}V}xsgg|s*S(VytQ@EJFCB++j-wQP z=;_^Fgoi(FTYc$0Fp%{XK>WN|wt+9n-9D2%FgoOeKWr00$02Reesi3qM8I~EY9RQE zrU+ojNeo9eZ>kHcKeh+!xT?>VS3{Aj=`w+hgJ+1byc;nWAdcXR*@gbZCTAVrg47w@ z@a!gqzzOFePxzf5^b6;wz$O5VL%hRVIVGVIaUvxO!bnW5;1G!R6q~`gl6lZu1_wtU zhsyQ7LGqv_LpMa6H42uOy@eK1V?pN*wX@ZymapPWazSiY?_=cIDG_BQZ94<;*rmeN zXKoZ6m)cBG7w|5YmSVHx4V*dz^63iJUkSKQREDyxg8(c_Ib;WUNgWRaJ@f(rc>uu% zuDfSwNOygMEvS4ryqtxT8E}g-gHgV~b_xjlNaae|sTWFZeB%*)o{mkzSPnFj%?e*M zcU12wzMZm7p#|nZEhowe7EgLBw))G(46j(flU0r6-FOGieYhK?ToLI^N(w)Tty1_Ox8YT?}rz=15KD zM+H}xDck+!{EG{he85Y$` z2z0e~pOa*=`{QV$11-Y&Wgf8q$|gCTptQZ}m;Cq*B-WmVgbZt#0~sv*f+8M zB}Khk1XYPWxpW#VHkXokbRMb(;Nkg)7^*-}gbTX1AgxQlbGA7-PI5ET)AkConB+!O z3av)Woi#@qgJ0E^`7;-0H`UcB!!7~7mcMTcdP5KD2>{N37E&sL0 zd~1!$6;Tx{5Z9aC>X=@L)rcd+D)p^RafYX7rFX61!dBddUP;MXip|XpSt=4s8|;>@ zb1CqxuzxcrdejjkV7qRhy8I=2@V!5k=lanK&kiKE3Q;?l`M0`}h&u~Ap^~iyP0TTZ zC?tL)Je#dd+#T=e>rzRLK0E`xM?HxNdF8GPmx3ukp%wSJIHxm}@0X;21T^|t=rbce znXIpyo~G-greFg?!Qk>=0i_svaT8f*9)}7=IZ&1g64Zkgc!2~a#Y5~;h`(HKa_E}g zR7_V(tR{r~mFY?LktyfEQsH?Fkxv$;!{KtDRMaz#z#2px(G<%0BMfgU#V$5Zhd`Xi zVC5CILGPwIS6Gf7;KavgxL!apKDNGr{%m`^RGUU(H_EB(G)cgl-dU56*uOS4W?mw} zXSAVwS#?FLU1U4-N{ZQB8Y~t$O#Yx+e@5q+uStaKP*ZTr==c#J3dyB7)YZuiZ4d`@8F) zn14@jyG7lkj$i3p*HN?a4o&|&V(HuBZlW}FCb=T};Z@i+ft_fs=H~jugi@VeClO^^ z`lP86L2*qaq)nJWvjq7I-CDx7mSqAY&5@FArURo#XnJD#Hb9^3oScwfcJmyRcmYAv z>?4bWny|)b2)YqpWtSko$_SA<>ItKc2p;_IhS8r$1jg<8I&u!yTKM}k+d(4M%H&B% zCR^&)sh5&ga2+f;A!%b{fK-K{P{jYo-g`$yl{N9At&aMQaZmvV1RR1WaR^EdDnWA2 zU@I8`kkFWxfYS8%XUErf$ z&z=#irFUG}_u5_>jcg9@vl;$q;70#VG|~nYX*PxO8Y)UtaNL`;qnoeKLwTT_x5yPV zRQ+@KKw#tRoo-YEszUUakZtymW!Raf2bA3g?_GpFIik$4(OHYI3CH~sgyqVO?Y`$W zY8n72RNuT$7XKOAY(_U$RaND>O*J@a5oV-FulFs7FZ;tscaS%!NTVMJHo5KZ`MeD~E78Q%+O=Y7^nGC0;dyRKhBk9Xg>3H9|9(oqL(9SJ<4o#7s?nx&Z0 z>+t=5VtzLO24p-%nSl06MEq&>=$0AxPGz5zx0E&5LI`^@`2BTKI!hTlrSsDFQ0#(~ zzpNdm_D2wLkb#{xYa1goH{Y_sSmnx?OGm zCwls>9FPzf~X-cJ6Jx5sR0QfE1k2q7mxa9x_{=j(%Qv~@x^M{#{E^;$6$ZibS+hDIrYJwQKjw& z2u0KrJGmpHbQ0iAc)!(ce5Y&tA$<+KpriSf!BbQT85vB1cHKsCvE%z=@LUi{WmWB# z7EhxpDe_n%O#**q*KeBZ*4r(<=Q+KP@hpowsDAI4iKsnPD>|+%PM6`pQ1;yok=zGM z!?)b*W~*v?NBFKa@{#PnJkYc3v%Wf2DmDS(HdyPitGe^0(;z_nprj}6>zR$MRhwLN zTkW~Y_oC%|G|!?>s%2YXULG_xb9`p%34-J8mSDGcTrRxoCi_cm=dHmA+);zCq#dxR zzYmk`&`R(K0Q^~{OHHACZcj7RH&p|J1A%bIPX=5x6np;sc^2bo)T`ap>yuOmGZvGb z^oI2_nObqV<`|_ z$Fuu-;~x089!SMOIO|Iz^N|XHgDoVg4(@_sWOMu>@oPTc7XOc~r4&ASDtIX3@l^7f zwNCO7$PoAfk=$3WKJ-)7f^Z<@y0AyA?0^DW$f16176m#RCH zKNoYK^P?a~3>At_etAPgq@bukM123gKdK!%yO>+-WR~mRnZ2t%rr5a!?LHW?y87VE zq&1i89Vld5M@zl*fPy1^kW!%%a>Hbax)pk+t9*WPxrCi8|AJ%JxY7-%2Ql-5*pR%A5w#chf2%N5+s;d~z!sP+~ zMFyBaS13@omK1={oDx1aO?pG5b^HqsJAi3S#$X8Z1u#=k1C$Ew3IIZ7vlW$t>Nu!b z6KwdD^lqmU)GnEp-uEw0ji;~OuvEI%=;dMj!UU-mQ_5Gl9)b1H*(|%>ED+43v1f?c zWUZv|?qh031j(Ap6xGFN3ld`&w?O{)5U1cqo>(-&zFuL}8YpkAjd{WZrR4R#4@q5X zHf;x`g>_43+i8Qh=e-4q01yjR;6i2lJ5)m0di$v!`uLoZd!0+tgB2EX8H42yCbyyO zBG}nzRBbyY76JZB zceVmR1jI9M3B0CZbc@Agj#>;d>|>kvMY#wP5FPN$ugON37S&E(jPacfZu5IAbD6-( zD<{Mrm^pP&tyet%Px|#{C#%kNP}{mzv&O5p*}J(4d8-R1YP11%-DlP60}7h;j9kpA z9Z&`4?a1QEu)PT`5U&{dhTT#Um-AZvS}!7@U@5k;cN;`W>UoIAE%2P%GgT$G!MfWx zI6{#+Qbg~%jyYpFRxUmfnPXJLqu1^MTorLp6WYtWBxG|Nr1fZ`-6j*&bGKSEMh@$( zh1-9s142HBSAr^c2)OUv65yLe8o5S1QB~VtsTJ4jYEaSx73?Ez3?RLP+t!d=b|CQD zkSZ%Rkq4wWabM788UTOdgv4sx6BMle3Kjj$xd1H9F9-l+V>kt6$=O(BDQ$Ew0pA|PEjeXSE$#l63{<0NZ@$^3UisW0Kfmx! z@L`pFbq*ewe%0deYV@l@QTB>Uwpx%{tx9)R%i((^8=|EBt{7;69n{W?y;@c}@y+3y z;d-45T)NW zX7GDm@QMTVU>7c4h`${~CBxj>+5ZiymSfNfJm#3dHc z)eAKtM>a-;S`lv}(cj~XKwWPI^U;1s_sPhkFmXIosVJM}#r8@Y$Tfh={YpW8VI3&C zgZ3SjWOdPitf&VUSB4MxYC+%*hXKnJ&Hwh}dwv4cA;Q7+zkQ?OiEQs7Md17Y&FMt~ z^1MH7Ipvnc8;0A97cPME`%~bc`Gg^=CMHmOph!4K$$beQ3=8*yu&2N+_RSxlGxm%( z+j`(AE`0CqdZBnYAU7+XbxID}f;893dux!87vc6g?$FDdcjwW8jj62{I5PH&=8&6E zZ)XPq399aF!5>VZp{ArVa`3trLVz^pPs6JB61BpI_U&a5C?;^;$#~<9 z|4i9G(+ct0>QnsdmOsFuoBhXJ9VBp-{+!*9v-|TiNl%Ijapz7D5do;a%lGnf^!%%5 z5N3nB#_t*(9p>O3$!+}Po&ejlZO^A1CY|r?g^sr576j-07!Oosf3+r!M97j1;-17(IoVMfZoBloKUn8$ zW(qLuekm2qY+`0wa6Q{o=0Wal&;LL%gdYYANn6`NdxUjG za;U)zcphYwWypFGhMlX_0D+;bE|6H!O7G~y9!}<&NH-`+``3t$qm!V zW7IUM=WnV-BJoK*8N9MI1ZiVl2pDojVYwTTI@q1byGnOPRle=NI6xR`?(XIE;Y zgOM9X0Oft3QLX2Xqcz|pWgkk4Mh|xTU6!{TX1hFBLw{Fj`vvw{9XyW4JPE89n~kbi zTf4kkSv02b{`mE*z7N@sq(4k5fcBtK4r4QAwT|6kh*E|gzd6QeKqdt5#0VXD#vpY+ zsZXAG^fCU?%g@(|BPLuds^a4YY^?YV-?fWrGW2j0!>YRi+FEK_8suver7cR95vvOn zWiKKR_i_OS#OB<^?ZyPZJ;&5Ixzeg`XJi;Zh>G^=8cz-VU4Ya?Gs}`4<~|dgWYXf} zD>lEB`h=dIfj6(bLcn!P+^xK>k-$tcKiwlENhan5-r2e!gh}ok?Nwb31Cnw#N`QFU zGv`Tn{=0b?EL<);Ng+DY19WmXhRV~UX_S?C4ZUL|wCAU5U?*pOhLD!zyp5Ma&On_$ zGw(6X4{==$EvM=CP1B*j|BmdMe|^DV+Hk>oz1 zVW~ULIr1KG?AxpL%Ur|SUjqpQ`$`emXViDUug+qB4b+J5i3W0riinWSPlO6F~p6|b-w68CX$L=s{?8Cg1Rf!Geodun!1sc z+6w(7fR@_R;|X2=&yrtxGbFh_BYp8YsUnxD|or8AaD|i3iYX)SrT>TRnAKH=XcvT^G7{6rX{< zLsjsq4{J#-%VRw7i`gBp?~53{R<&MF<(nM6C)?`}NE{6cvG8!)_!Q$sZoAUPOOQz6 z#|lTA0ff8z3lq6qx8Vn3&RdLEYp9$jJY%P5WxkuN3nMzN#OwoY+X+S?k-bzuwMI!Fnmu zL+=c|uI>x=MGqM4z8VwBMnxy6j`V@z;2xvTZ96K&;f=4gHw5;u#u;!K{IZ zX=-W4CH7xquGP&iD6ECZn_ld#e>WhM?xZTl64K1efFFl&x6;wfR0jmpN@Ogoc&dyD zSnd~6oM0Ou>kFE34gbvXPs4jhhUWMqAS{U|PHw{gG#H^GUWwMHvg?ZBku zc)P_O%dY^*<%P0{hnKLDJYnyMR116sjh*0t?`S8O>`uG^)2$Pwvuav}VeIS~2r}o! zKLm3>mweQ*y45IRh)*wx-}=kCGfT`vGFVFXd8$#WZI^>QQhq8yu3OlJA~zb>y*{kY zlvT;40D^$PIL{xMrs{z1ia5T-|G++Ya>`6%_tS;kYWvQ=KR21aS4EOtwTwVW6SNA} zp^YJiFiGh8EV4nt|6BZQdppnieESHwNqFx)f^Q2GUdL+!SjU9JlX7M&E7sehc&&MN zuTZ8urao)~e0QHoAh0pmz4FcZIP5Do(LAS>3VL9!EdTqB;o65S61Q(t@!W7ZfA!m+ zC%aZ8a8)J?HU4@|XxL4`XlvL>F2O`IUWCv!td(FxVVpUfGJ5SUPOQ7ySpUbJc0YtK zUpv7qF1#U!b<}_XcpQA)zsOrQJL*I&)6GCnF!(Uzmw3g4#Y!ZakU6akm5s0Oi(e5P z`*KD_n&4Z)IxrVBj@;&y!cU!_LhrR}|KN{l7T@+-**$;Soot@Z{`T(GZPpj{(M~8& z@Y-O}09qBv6H_rv@G07ow?@c~#LuzXSLVjkyDphiwcI9xDFg2T;=1=}x7(CFG*^Ag z!#Zz|7hqT`YX}0*jPZ$0aL4}pz4Tnu_KIzh@FbOi6P+#LJA(;-l<4N%8ZIh&vA64Y z%L`0cTH*07_Si6jrnukf23*{rTFG8$6WAWTZW6AFpvQLy6XrNENwhNE{nlfnX{co( ztGkeV>>i%N0Nw3w7*CLo@F#$aoo>ZdcgnU8XY=C-p+#8hBm9a8;{>t{&8BH#6}I8i z9G`ux;ok9VhQG#}G??)3uRl2)_RRLik;q~2uc`q= ziXGd6aN#2&S?rcewxfa5z;g6TONdlXvSUda@8a|o*j~;Yayb$ZMA->W`r{2GQ24$h zPA*0r>BZvFIR;RZzQV`j{(Ly@MOTX>DIP%`&tgOP@wlHIjazzU)EXrKjP4!Wd-kCA zU@(2r;}%m6TjVG^;^ghT6P(PACCm+(^5L+Bx-T8l*vd)p9$>-($6|3VFv(=8#KNMN zE$(n`ZZAR+<AjN zi9z^;6da1tPlN^@6Z#v0P~y!)Int*%=2L9avB15tUwP#Q)Tf=dE>aMi$f{3qJfPU5 z6V_uy%dUQBYUgbGkk$~#lQXa&zMYMa8sedS-D7B5X*oIZ9QBrC7X>CPgBPse$i*Vy zy_|+IX#h80FsA({Moi@r4hSzdUQbHTMgEyBL!RxS-IfjVh~)vCt-OGs)<$v(h$HS| z6I^sh1jasG8ZM-{0x^7Xtzv#QJS5^cB8i9=R84^?uoi1Y4@!wqmzh~loE~2nQ<;c>r1O#&e_F9)pngL zIM-Qt6R&l_k>5MNbMvu>;xz5qubM?K4zAY9NlP;V2P~EvC{InzMkGg2`FWgKi!HUn zucFWZj7dx#RmB2mt=leL_3MGS+xpVXj9oG@jK`=qQ&TCK6E{rf5Q07e5-$*6c&lFJ zxN^1b>Qz6{@FavJIK-BNoGiTRoAuX01mX!!s;ak-)g2TA6TJi{jJNd}88)%8vnxRD za;5`AX*`FCFF^0GAs7dp#%?}6tvGUi_*=4^)??L>6(rX zb&4*40$(yTY_eSHA8?q>DtFd18?YCpICRH;Se;}iQ#HATql{Up+1GOGb|E)jF>(5Z z5B~wi=mCckayFXWV}3r2XBOBKs;YGXe_DyCLl5{z5nkRP!qwe@jtaTXI?e7^JC{V( zS+`%VX=t#A?(HxJbgVArov}Q?OqJ(Z6wmke=UOUJDB=vv56Pcs>F8yAP`miD++ehX zv^h+c!RR!s_?HUxCL8Lyx*1jj%^Wj_@@-~R%HzYJWG0TVc7pd}5{+*6+SPa&G|xmy zb#q2Ly}T_OdDF|PMEgAeg7nSx_4zCJmnYdCJW%Px?77V$y+*ZgG9s^aa`s4`*XB;I z(pZ!MB!$zL+fw&#wBv$0PzE5^_hrw+gh`T;Bs<64*rQ!+Zv)+CJcb;+-;5c?dDPx_Tl#9KH+O_FSz)@eN(=d5cpxoR} zww&kAy<<)L+Zxf{v~wP{*V!()q;vLSg)KtYwm!tf?f6w7|b6tyT&(@{FkzA4`WtYPEfq4@YQ5%dP;EQzGtdL*r9^?TJeM^0{fnd3v;tgCYpmMSnd zl>o55{Xmw{G}5i2&sUYkQY3asM+)#cep%OLqhe-$d-ui~VAGV91g*q1iQN8g;D~@K zPM4g&@5yxE4S{1g?%$^X+Ffe3icuDvT0vE>%o+e#|pA7BOdqs5B8HHs;m(}yGkQu zBd%??ytUIUx8Kgq`-*?@39w%7y}`l7>z6G&i$=Ff?~*uY;DVD_1@x7plQ}_i!oJ#0 zJ;6I6LfaQttH16|euVFs`N;SfQGgc~_zaissjMCpRWUm9mgORGvRTc4vh#29f-!zv zRWn<~4%?fneQwrp=jj}PQ+7jWhCDraU#4G`Q+?UwV5?T%;q$_8@y|=i_IZV1wcf$! zc_2CjY*^q#Lg*DLPpb0G!kq;!N>A~aIqxslUp4B%GI8$0+eb?)6%SqxB6Nmx7k3+G z*EPg(6pd3K`#yXYWi%k{1y{Clw*mRYn-Fu4tL6J`b8g?!_EVk~wKQ@YwPByWWW=9> zeg04Fqd&6B47G-f*Gr2J!j}Ow7>uBW9)^)TIbnK*&jFP+tC(o&cdQLsJ)m+_yXE-Z z*m*LQeqtx}^-XT;JF?LN6adK3sQ(2v4qT0E>7}K5%V|A1w$o|-g(X~2C%|bjq`H!YRwU+stWWOWl=M|+xB-wPrk@Jf8 zz5;2JQez464%TJ!daHZm;#;tXn9@`&)2o0H&ZMh3lE?0Kma6$stkay&AN%34r|2ZE zfrYGdr1SSa?E<<*ZroVG%GcOnaFnS(`ULkQRsql0lb`-~ge3UH>WjbIUE`z~!+-kU zVHW~M_g~?8{IlSvyCL2-s9WtuFMH?FydmX>4|E=f7|_k3N-PA#=ETFk$I;~Rr`1d+ zbsztE9$rlGA3#4_PC9A$fBbn2IN(15_VE92^q3j=-~QL|^n}A|H?q}+2VIOl97lk_ zx4LsAi|%yEPNH_b$H)>8sXIZ0qzj%@@KZScq@Lpc@xOhxPYm~egqZMDf}i2G+Rzg3E$#zq)n1a z^ycLg5D=JMY^QW&(bUvpeKDIB9c0;)#HgpSm+Q@Y1dV}CJA4S*C4A=hTVy_dt{A_G z@ou?Zee8iarPsb6zfI>X0D>pQ$F}VzHnUxHE+4vQIEp!u+W5o;%$+o-d3t9=Xa{wl z(LmFuF|~20KW1OTIUcoov|QpI`F1i~AKU4j>;%z&FWbyUpOa7+;uykn4?kA%%M)ll z@jMVAPoANV<5X(;DUv3bM)z}_y@SDsza0t+^Tn=7^s*f>75sQ1Mp#8SJ#>cb3@M&J z<;xnOL^}(fgh%cl+b*)2x@Im;XP)k>`{Q86JZ?%}iC{}(Uk`60`SOrIylh_%5mjh8 z=AA@EPTsfia+IvB5Y@t4*IZimTI$eyz_pon0t^Z*Bl`?9nJuK~EKB72i7q@O4TF(M zqh>O5O!wL{^vY{SE~}Fq15ol8k10Df(jzSTgs*7XW0biSA(!Kpd=v1#y8DZv3WS}H91{Mc zyrMwh4JS;Vq9UTGE^C=@vihUkH%wO9qWbCMiRduKE0t8+rk0%%fR&d{ zm!5EwyWw$uA-qFJg-H?5%E7|}GNC)&4U-5_M7aEs{H86HmU+?15n6(^${y=zYFV0m zO1||Fa&Dwc>n-Q;O;T?N?v1hH(HxK#Os+5l9;Y~AOmuJY=}G0GQI{AbKs_!-+hxvq zL0;(_5tuxmUBzS@_m8RTAkA>p%e2UGFRe01qz(AJi8L9ty3+fmdB_tAcH_jj0-L8NRLZh{f>*m6|G&D?ClZZP8YS9Dj>m5-H)>Yx zpO1^&BIhQ8QnHiD=XA}S`2pr>gp~#mfJQx_FkC)I-UkE(xZG(XU2ldqF?ny6-{nPC z@5@l~6tSqcA70R@$Ye-CJRavOCtKs0M?bj}Mv9H(c49}y2oQgbpVdv{r07nZ4`q-M zH!-}km;w`~pk>>;FaPOg?ISi#Z|0mrBb5wz$paRx&54*z#=g4ntRVmP**qka02aPZ zFoE)-iHi3q`T9xW2fGK{J5fdx{f$trHwwW7K#^Y~BEuaU-2^fJblTHaq63U10%`_T z()B?6GjaZ9Io->u)tR}4xeOy|cP~I31Eupsr~Sr|i{;XW=S?z!5D=loevy`~+Axi! zp@$bgyA#t~KNzi&GY$3?7VuekkY^20fC7R|FDMMGzDAJhXa0a?lR5O2#PHqSgZ}OQ zuWVKa&QR(e_7o)iZgRUYoRf_Ku7?l_cGb^S=xK$EQTg}azPe?u(Q5)aIvV1?uspAC zyHxY$Jf*LT96#B9y`MhCd6@cX!zK<(OiLrT>x{nha`o3vMKe$GtWn~k<#M){o)Q~h^CfJ(l)0;wWvR`^Hs2BReVseB$77Ld>>?-Cn zSCjgNNhAXFDXtd(A}u2a4geXUf;&39-J;|UN8Exv^Na|O_S!#B>g;a);J>wfhe4JEh^l}C!AUD;h{XsD27V{2PGja05~ zHcW7T1nsk5d29`DAJkU>Vk$>M5I11%9v|}rA z4Yd0O{{7*+RX(@1PW!b1BOGcWuQbi+D|gW9Vu?M-u9K_6qU!jbVv`!CtpKzT-e2=g zAJY@E;wu2((+)J0gl59tvvEFkC$AmbzB8e>H-V~HN7cymJ%xl1Tx9Ms0Y~|rmdT5I zmDhx@rr2af0M?HOu=BHD!+wviBE@cPyV4sP8s;L;aHd+%ici2XUo5~@4)oJR@KW^0 ze6Cyim?1xG-%ic`wmz=N#r>Q-p;ASdW-lV!g~xRrdoXf0*#to{W92_}kqGTfTjDGd zAVMoa>n}pvQv$sB;(So~<1Z$XKs0TYz>)aG$dEcs+1(2J2JW37Sto=oal3_fu4LeQ zE%o&W+JC1&X!ok6{rKCoB`L3xyEa9lpVFBx=w$kvGK(lSRP4~tIx)gt-Fwn(QX@?^ zFU`}X$YaG2}HD?<jF); zD~Ms^L5UpGcYUQr0hvj1eziM!MtU#CF@M?aPoIeacZs`Q6c?y^2eXI`t`m1XAdQ<_q#a$0l>!j&3o|3y$?408;6jdZdI`vY5=!Xc4Ex7N%@b8q(*J5coE0Bx3lEdzg3 zI0>M3I>-O6pP!2J0iz%P4eWv)RtYmGbWqzcyLMmt0%!X7b(&R1s{LjA?;D<8?X=A3 zImgyI^&C@k+NMwdPBPdOiq)sHdLz}~B#GZWZw_ud`v_SVPOQgZnvAGDX+dEED)YG{ zPAmLlz$^Q3mvhYZWVu>5^rTP*Mwo>Zja+H4%Txw05`=LE(S~?qyt3|YWFQmz6<15L z1$JKz?^W;Lmp;dtCv?yPf2w@1dyT?$BKN8e6-BmYcHpnDl+;IRS{bhOJvlQ1Lvf#T zD<-Vn_Jj5&JP(phLvhk4Hbt*?*fnfywrXFd*KIsdt(^H*m^u!M3TRgPHx| zNlTyxC#I0GRCnKR#cQR{+^a!l>wX6cwcmZWHSk5`Aq52F|5@*wF?-I+t^TiofM7cj zS5YI7t0)7i+R7>s0MYWvR7G@Jnr61W9_2PMiFk63)4NOho-0<#O|{d^ax+(b@9R)J zV&97_`83SlK|+v}BD<1FwQ7CAt0^p62*EG7IZnFp;jr89T=-pT)VjJ>><5c6&iQcz z!)t8~tm|JMg7tP@!mIYKjhbrP#y~dzZ!U5|8hi4>N;}`)z&&Q=C?o8$iVZa~98g;g zMWl-#F2J6>T-I{b-J}Q#;@Gbx-L9Meo`-k>`9Q)n1n>PfBDccrk5I9g!>kn}FHM!1 z11^)JPjkut+I zJL($(+scP|rw{k>;a@c!>fn48S$AUB@MDQ*;;ea9<2?`lPxGt^&%yA)*BDHKou(aENsB<0L7+g@w5vl>NU=)X{*9=B6Cu z85Y`>|MXi)p~2yRgae%auxeHnaWJ!KD>+X&NJ>?{E`X3c%NdYOVXr?L26`fv7#+KJ z3Dkx{@;-1sU3Y27=&7ZlnH7KKYRh%Y<}I}zRve^^z@r2I0}fkUedg+Ngx#I044MGi z)W>9CI_p5*+4G+VOGB zqpPJQlA}3G0~bty_c9Go*7h{dM4};gWokn?>KbIJj^qDoy2T$C#V1Q<{aScF=I4WS zGn6rgb%a`FF0Z$>XgObG;@P{x&yH%z9SwrA$MQPOSnho(wyKkc9jJVG@FU z4#@zH9){;aa0$~_t^_a@XGY1kJfGZFXuckYr)WDr$le1 ztF`j2&vlQbJqASrFjy|Zs1)l9xMALwoDY}++l4@1+7kg6Dg}A1mefJ{Te667@40hw zwbBkC?QB4N18|%(PS;NBMjumz^~~J-_5VU1sKsnYJ1Uy_(n>4@LcGkG)*PI1cClG< zjwGi@RU*4>THhWSX_vH|wlaAB6fDJm%VD%xdCe7atKDY^B?!g(6@UJ@J*FQywT_Sk z)6}sO;QV|v41M9%>%__au-80rxiyI?K24~T*xd^w)*;=|d_vb|>FaRa!rUDRaf5b1 z9ev$oOUHO5hs5)Pt56AzHao-J?5J!QsX8w*hKFZ%5uH`|Bp?AQZAi1I)J^h0k6njm zvZMT%^9f#pOp$6(wcrmO2^LcSmi_c(ak*RBheNv5f_BXLiyFM#Sxi-ft$P>+qz=Ht zPw^m@yObgw6^ZN`nwJ(dY)rZC5@oYdlfz4QD%Tb``8@FKga*JZ|LGxbf77Tv(^$P^ zV%*})q;lLuS9z_p#5MmNe~=ZfmYTX~UFp10vWR4ylv0I^ZqtDSd9)>f@$hPhmkbLHp4oaGhYAhgG z`0xuXwlJW#q}hbg0gkgQ)@uXRgNPQ2emwFT%4| z-m0?bG>o%KKYE)pG3>%9DYy;R5lD~#@R$7W0*u0mfltrCq+S={fSi#3BNH;|$6%jR zpE=4WY^~*N`+AA6Z%4oVpP9ZqAwK_x#*arJ%z+1xnRxmvMxst6cYt6? zOdnT39zXLxkroF1pR?lX<@wskM!i|ENBWs`6fae`QCt1Dfz`X0eMKGOZcNXI-IZ$< z;nhLX#)v4kh-Vf2_O`9}u1%q6bDBYCZY9Sc%c9R#x?^0&K=7szZhaTN^RtwG>r8Fu z2fLCKd$x#6hje?$oze>}{)pad-J8U8C#U5xNl-V^5lMj6KooSK*dm%0>Zh&s$J%mj zLjh_0=W@C=icEz$V_)6&+`C!YB(*B62ko>HX&)26fU@<;eWS_Y$@&S561^U#;aP$b zM^F@VqJMCc0%Z)ct7E6REk8qts5$E?1w|PM_@WkRs>&0?S8>LM?C1QxJ8u{_?+yBc ziHIJZaH+WU9`d;Uo~I)f8WP=4jJim%eTqD~YZH$(Ho*VtV3|7;WdVHUYpcTs^XI%PmWiC$c9VaoWD%d)%(izhK(ujsaEmQNe`1Ch#1 z^*kpW8M()ZJ~Vl;vgfubvJSee$i7~s@a(ZDE8H!MkmtRB{d)V=+M4ypZ22g85s|52 z;`sH_=J>q=wK}h;Me4@s+{+~}6CU61;?aH_F>ZJ2Dy>ToPBoeMP;wK+pO+QM%KS~B z$O5TiQOT>>XZKAAx4%W$mk^QQP9X zFlXky(r4xcNP6JK7-B$?NlkMeS?^heQI+Nw3Pc2gJ>_zN6D_3Co*dgk*Q2;z`XKC< zeF}X?pjsDjr5sn3<9b8Gfa#XE_)iE3F zx|)b+hBxx!U~=J}8+i4SH+R~0;e99mp4EP|AdYdRd>MHO=X8Vm+0r%rdu;++k7Q6c z2i>@Pu|E+0QvuRU@LkhSO|k>LnuG+s7KylDVU$XS5+WZ%Z?@OIyE<|cOl}+P z*Oq?eTL&ZAwdiD7Ln|R%%dAa5!*zX>^#F#*ODK<=hXX$Xkx67{R67H>4 zaZ^`0hqN2-51Q3l6p%q7aDdWL*}X0A$WVx6(=-I~r%H+f!B zzoX>6cK!W%(*RUx%$*+p5-CWVQD6r{JJwYU)b0+h99{ z^sV20zKbL4#?|)XIr$Yf_nJWs;+oT5+%}B`Nb;sPwN1Jm*n@dh8Q2skp;fJzUQpl5 zqEJxpES*D`lb6Mt>)B;E>=lOEKj+3-%Kav5f7w>$KbRnTgeU*Su`}^X%;EdEw|Gw?z_`lFARk`B-dka$c1ggVTXu9^1T0_h9;Z9VOSSW?{7OOp zq<7NG)`0W(<=-k}rJBJ(vh%Yqy|);h(n`0>1|QhePP=WtQ+L{K<6cLD@=K$bEY}=d zvR(L1imd3N_CRETixpVij<~iW^M$A1(7-a1A}W8UE79HLb9-KFXuuU_@-6&=ggsxlhYN=s7_#Stty zPD?mX|LokVs75o@mefC0|A7W@38U+7uV~QdB>@}mF00b<^;RaehWcHqN|r+B9T@<+ zC>B&qug>4>U$2R?_1TK@@QnYeB6%Z6x4yJ^f%GXU+Ms7|HbW#Qo%wO?dri7x-{{K}Fi_^)0BMGl&D?6;CFU6rjwB@W9i?{=2C zrJ5XTHpkDr1{xAlf?1gNLcgII_N|#2qy$4u4(la^3;reAar2*6Z@O50pXQVJgER_k zNcHf@BIgpD3OI}6-Ja{bD;EsLm1;cHPeJZFk(9Q~w_a@rGHBj{T$oK7mFCYYBV}<2 z7jdY56L>+?!b={MJoRXzELxmZSKn8~4Ff1inPkga^+@I1M%9?Ccf%s0&;>QR{kvTX+G_X zlN7}7^~$jBl`j%UtGzHD13ked2e~#y77Zv=1`uopQhNJ6_Y4=xpFdXF!aez;>0dJT zW$xn{1u`=D545%uo9dD#Ha8nl`QkBcE#@yfxmy&-)!Fxu2+S8(@=l9Qwnt?eXYs3e zHR{oLSF-kLdKjo>KivSkV!#Dn6!|Oem&0$dkb9x|4Gp<?i=Sov%51aSCk28#RBgJe1m|-`pEeH@O`rssA;cl*9wl6L7 z-Jsy>W8J|hDlVD$g{>=j4?>Qy@k>K}D}`-mwHzZ2d=L1ItJMM4v*vdAJ!HjyOJ7BT zqv$_+4?=dqYnDW*#bzakG>%`xOFP{!@J8tn4e|=>O9>v|wGHVhFLX)$9U~IE_KZhH zTKJZWO0Wz#E+3K%=8tou|-T5TuGFLptYPcqkeHU=)4rXm|8 z+X^pLj%HAq&eC2SK6|)@Mfv^D$|-vDNI5I11GE)8%|QIprlwPwviFXXKR;z%N;FG7 zDj;4`GNg$(kV}O+RnZVf$iJlM+3UI(XpQ@NI8yJ3s?CWRY+>gcu=D1XvjSi6Uz}YG z=4lzq>AY$^t2jW)T`KfvO3oe%9H|=J+ zC#y^}+Q@6YU70$HLB#+hEx~2|v*v;FIlSgA&dB)FHi||`Tqv0m5;%Ck^52<_yAT9 zjY7a03*u7I5uuIo@1ju_w%tbcBo*=fBTqZEKj~Rwvnov;{Y9VQo>nGg@Ns`uivsgJ zF|5bR^g_I^HG;(XLE|)dU9+!usT*)ppEOU4E*q;VCAW(^U1ovlc$Sc8MSIpwjSp%~ zm>IuP21iyJ?M>iIYVivkiMit|ezB`8S^dd-!7|=$AgY-wHPMSiV>m93S^`znHPq!@ zGp`k$HMv7G#;+PA0E#oxj9Gxm?A?q4VZd_+MvK`|nThuZSni z$Jt(T&SgC(IG~m&a#0QPfW-a8+Lt5pkcwQhRW1xk?LN$|3fES#d3Iyp6?#m_>rwOb zQGdfeZ9h#QB@(^ilx^BqP?l~wfLKn?Dh=+@(HR;fxBczn?bFmxP!;DN{W@++RojLh^$K1&TK0q^Yl^pIF~%(#(KZk?8AVq~+@#q7O}R2wszO$~7nOLw?(f(Fk2 zEQ5zl3JW+Cg`_x&n z0S+?h(zq}lJWlqn*!r-=O=WgF(*zpz>?~P2p&2n=(Kr2@Uli}D8#QK49b`T#tw?r= z<7fWJ#KY&-^`htOU%^YbKpi~1L^x&UuqE7gcgK{A=luFl$J6A#THv}+HI(8NRK`3o zE$OXfwwM25HsJh}x|OTB>)Q)SSw*nIzzjafMxmcK@F-e}(pUz}#4_3}@x@l47GVef4{W6WmBXfvzOM&Y zZ4_!6J>cSZTZ3D4F9kI-N&iyKK%tf273o&VRMbq|H9R+z)z>An_%-l?vHF0?yyjX= z(Tz#l_ndZ3;E8Q#Hz1oN3}I#WyNLct({EF)EtK`Oxzy}n?Om`OGnSt9;8~+!#L%bw zc)pwAz9wNAJ1;fTwDan1kfnp}g#uh!6f1(V$o>vj!+cGh+bN~O^0r(d3^>IGXOFV? z)BKFQ!Ct-c({|8lNR)=NhDzPLj=WpubzyVn8|&j}r;VmXgQE3xkPE3M`$AULL^3PN zE2bXQ(yXHM=gs+>!3{-7 z)TgvT#T4JGvMQ}BYaRx8ex)lsKD7Dx4-{T3xj*D}tseg{OX-4b{WIaA-n4D$w>%xE zO|zkg%i%@xWita!k}_(Vx^Z3CKHivIZCJKxnts(p^`Depl$vk0Djo4O0|TqtLz5hE zs%d7XldZ{SA+u(o!y8FPMskcR|Ng2|ss56EZSlxv^!z~98y3C;+WqZCiRaQFPZ#dh zCCYar!&4hA^Y}-IYP#+wCEZpF(&k3@U-w;?59~`WRE^y3(J1PpTvY5$6_8$jvJ}NE z*G$_p6{Hc63hp-FpWS|8{q+^k!~)iNfC+9=uqFggjSGuN{aQd_v|x3hSghWqp8 z7N)gm@gKHHvMHvRv24vMIl(IU^wVrfh9+g@r%5_*-wqZUg%qv~B&ui?8Mkg_uA%*w zE>6KV>8a`JX<<}&{7S63=KkZlb7qhbj0 z?bkE!=lT!M^khFaD$&VuY%N)~Ezx12tEpoUxTisJ#j0$R&+5KQ<0BajPB=#}tLmRO z^I0$tmlznnMJQE$yH6iQ*)5Fa`P6YM^&8I zTcy7AXHB~_l^Iaw1-OK}kE`gxpRo$Bc%rO$+;+!?@BQl8WD@L9J=C-FqQI1J9rNn05gd%8>l`lKm?cS)^?GXu5Q4!+>uJdL@C8S;NV%wY>mM<1Qx z#k&2fgtDa|UR?cqQ~FkTt6}%_q--z6?9+@HlljZ8uIu?WBUW_|yZaJGbDI{G9W*c)!pjzFx;GZoKIU7_B0o<7J1$-s;4qX>TKc5k_%}qssUYUT zPv5>TQ&UW<{dM5J;Qa7xg&E1Tapx`vN=5W-u0=>2BkUIvIMm?2ia-mAb5_< z-R&lP#sbGO?l{DYu=qV!yTpT6GY*a`c~>{v<%B-8TYP^j3xi2?t#gfKU99)v;CI{4 z^III5S7MU>Rt&~mB8imykHZSulS(Vvz$WH^thXX$*KQ&0fT9e%h`Di%|ms%_*)7M~vDD8g81=4C?* z4rRPc!y~E|Wv|&_onB<#>0{u{+`hhaxhM@`Xx+U1Pq{+H-n{P+O5ugBO^|^>V$%GZ zGHlZOQ3siJ=e5e|J+9@J?m*FX#6Q)4{Lvc4hB4ls{A!nPyZ4|OB>CNGBDjjw!4fR9 z{6n8UZT;&cv!snN0)f!nPL@~;yZbFwJAxH%8Kj+RNpi=uJUnVxC-w2rI|I9g&xK&| z6R#CAyWH$5kv5`~H7GF65M97yW^|+_)&5BbZY)sg)6wNlBitAHV0Xda=uzbdDwzAb zwfFxQU2g#vb=LO}v%2c42(G9I5-Nhy-KlhUmw}sURJ(o&B@ew zsn{lggcF(U{Kxqb8(B-12iI1~nEiRhoGCd!LqMYW`Fg%t;;xc%?(&bGr24dgjEIhlR-TPRU{;k4YPFaQwadvgEd2F1w zUsYzBc?ymk5Yya=i@SC3@96~l{~k7o|9{Pr-T5#D+3m*-Gth7jsS*$zW{PHbx6BE# zKSUx#%&TpDTi6~yudSL~Ki;$t&{Q+<&C4C0tl^z0S*vyH!Jb(Tbv{IXTL+raH$6;9 z5ELQ}?!a~zS<86pXbLo|P4yn@#uxd|3B3H8KxJtot!Px-JQ>O?H~jTmUMVM}c*Ojo zdCesGf{b*UzP+QcUdCF`slk61F9F59-vOXkbd3BWM&~U@$}zyX_3AM_?L*Zh3Q>`T z#uscw4F!IbK@#t!k|;cLK!UuDx%W^uJOXu^WMFONjE$gWXHALH%`E$;EC)o^8w ztsKda=Okk+hUMX2>VhZvBPBX@ojDSNJxd-%M~!~NXXR!z2b=ry9)&+A8^(C0i)uC0 zjpFC-0jieR|4Dva-fc}-wbarz{0wuM6cUT-F>^u#g|uh)S9bYpK1csG_~XlKapv(F z5OFB|Cfx-#9X(getc|S|H?-~~CDGp`EUB$lyYIO%fa5G!iS48sh)%5-3T3{}%*|_|M?* zUt|Q#zrL4|#*bz!!?z&2F~rrfxVmX#j%#T#>GtaCCDE0)Wa>1Oi|;vdEU8g~TK3bW z^A4@5AY7M>t@AF}k8OL-JYy50Ml298OFMA*RE*~UYS*WK^rrFrI)<|8#CZVg zV}P$d>A4@OPU|&jZXTq&9dD_w3=f@1nzwS5`mmm^?h-RkUnLOp+p|WiUWB`Ga^bqx z$VP+Mv!?X(%~N@-wu9XDYE8=SI_kjIeFBIxO5JyKMc2H`eGxRqsmRYmzN~B7#;fzS?{S;L>Cqc`@r)kp z#A1@mM1u?7u1tOSAWuju>JYcGqOktnK9kN4`z-dP-P zVju5sXW3pW6KeI-*a0T#uPgthJ3s!tykIha=da5LKJd1U_hRG(uXMRZGHrbG8JHMH zI?@HXFrDL&!|5?MyVlo`9V{=*e%DUEA2V51L+b-RDq(Ogr@BP0Pp@Tof-P8eb=TT` z<1VvatCBp=nZ_4<@*PQOenAj!atP@PGYpK4bYhwj-tAw2X|$tl5-JpW62Y$LY}s{ z3>MX$e2ZOj8lc*3uUAwz=p<~fm2+@2S7-$hJ)R>kLM^B^1|)t-PM%^r=Zq8cksG%^ z795uM;lCFf)g41KI>NU6A2>kl&wpjo;F<8zU!{+U1aW`>&7zw%7|>*d7CH`ZTBv15 zRCwD!O{W|*$42#{iNuQ1h=K*`dR1W-DK;rH3cAJCq5EF9R}a3fyA+Qut7|GoG;@zk z7#id?zd=k?c}9VoP_kcu_V)0Vi3i-!GD4_hV68#^Zpr9o4d39ING7Me;K7pZc89xO zi+8S#@2n^ZPCinZ4KXhtcS!=xbTa714vLAi;-j}ILg!cT74t(RrRa;w*m)8SJ>9>9 zG(bYF+F7~_gGd)Q((=$B6;aq;NC940^~DJUD1^Hb?q)2z;;Lk;$HC%x={gZ`j9iSK zUXK>;p!W%vkJL$`xaz=9Vz!{L^EH9|iMC$p6xmgm{0<(4{=Y))(@PSQDDv-;5=VQ= zXLl!VXe>_n;sKpoWguE;^)Wz`N zi}>+uO47@QNyYW*$#t8U8HH5OMcw%RWIp9^NZo3d2&F)=t3BqwlH%XV?J@0x_Qs$$v`sdT-?BEQ|lZY6nb zEj=i-umI+*2jz%Wzq7pkb>4+>bUm>X{DX-Vy{8g^EY!$4wH4jVknu?FFu(wEt`yi zjZD^C9mfXhwV0dbnFULNay{1vi*i1_Vl7r!zA{*!F2v&b)u+U!q|T+sg4v)|3eA*O z$PY{ES;huGWWPz(xkr{&I?N?r6SsW&!WnuIzPz7AzCb|%?OfzQm~|EG7c3>&bDRrz zne6aSe)8pajLbGIxYwX>NhqpUp`1eTYY|)|T0?XidA&XgRFW!+zA0WfZHTB~#dk$_(>+8VS0A=!9S;dE0aljhf|KQ!uqlyJa>X zpAuWb!f)@t-vVNcUyV}+UEisZG3%jfoxkyi9BQ@ByJess;@x*ZtETJKYb9xwjd0}Z zex=nT3Z4%L6ejDUUm3_5@o%{L=LNkuxF%;3>mVp3Y-c7k6Q{1g!dFJLwIf6opAbApltr} z<(c@MehTy+e$~io>A&Ws>o=qRmv~PJ>joqC zgon5K@7u4rW{obRh9!5Il-^ot8EINWq)l|eS#)ozZ=uLSdwLW%`J#_jwHRCTbW-Sx zA0jgZkNNPC{$s@#&t4VZ&TyH|N{t#4xTL@Z^7nlv+5jGDuO~Wf{O8nz@8|#1%UbOf zFhMP4+0{!g(X#KG*NnSORH`=Zyi@0@);5;+eA3>&nx<;z)?dUvp>B|;-EwTe8o;kg zduNvZ`L`!vN>Y_XrKR0B3UUQJHEm4QbdWgO;I{0Hb%7#FI8oDVZB3n@V~f$zjw`;x z2k;p=6Sx7}3Z(?V!gSCcp|>Iv$@=z^uCt=3kxgPq|Kryg$A`irhmX|j%{%aDQ$|?1 zN>u%N8$?OXpxNJZD&%MHT!V0Pd{W~GHH*a#Ze{opBA1so z9o*U#sFLL8uiW6|f;*j(Cul)gSDwwQQY>xG@0&CPYL$CEkX$ss`*_^g&@jD4ze!~| zg6jUxT6DSaFh_36&b5P}hh+Z=YWOc!;l1aH|EaNlzWp~(z`Bk6fd)tq)yqyD#N-A1 z=f1iXX#c3ie1+D81ZV-Awb?-4$V+@I&8>;zVC%F*Ov-Vtotu612-<0BVpW425yBvWpAQ4)_yG8Lwp_CBM9;?@{fP%XK%g7=>nCh{Ne z#1!tIO$S`}p+`C1Sf5ch7TyV;Io*A0lL4K{vb?y@-YiWG$|7>;smX{-80x{qIx{o- zsR6Ap{rEz2nArUt7sYkHcxtUOHZIGCNq2+uXLk#Kud*V@elPJ~NjW-NhtT@S zG4wExyR!AEqqt`?g7-I!sWci!?b{%uj`?(Sm~EKjaBXL%I(&(ld~Z!gE;MWm&2o;g zIGI1X3`es&G|b?7-a@_)!4_Qvn9*nvcz%ojUZz06o=%Ua{yH>HX{@)m z@;$SAK^%ySuFuwSEL<`e=q z2IMj+`~&{upB1^_Y5?wEkoe;xO-;>XhXVy>{W^nu^Zf39yYje>2<^fHN*c-=A00Ku zG;D{);_4vNjSy@{2Re>H%VYuu_Ct)9_8pn zNuM9JrOSnfp?Zw{sYYwUodhT#2SNJy&=C{4BWf)x3z?7f*+0DEh>5|@ymzAzi*>UT zHEUM@=))_{Ihf6ej5(WHDtZfE`1cwIk^Y+oj z8@|J3cA!vZ)T%`UH(Z~r9m70HFNt4>my!O}qrL~%Dg3i)UKOcpYUa~(7Fe%@Tkk*+ z=RUZZHwe8JNFWRR`>hCa9*#Fx|2R=gXpkco-mW}Y>pMqJ9^73UA>Lgs(O)hX*#Dyb z)av=Sc5hSAAs0W@cJ@xWWPRXyN^gnD?kSIHoBgZjOaIDF!H)PnDR5QZXF?r!+&V17GU8?8*Undmn1pWc?OoZf2!-9p6ENwBK3N56GB< zuj~-t&yy2PKH6Vv>{BgQ*J8{FGuL-<_ZPf7r??s2JGOGgGvp(q#=e&e@3oaIn#crN zsTio0vKIR1r?|Exp*O*xJ(o8}V;AN3gKZtPqROXfl7A{&O5++BmE&46N-u#jvAldE zz!6==seC<=Wf&3Aq_3Nz`?ta`&h+N#+HZ7GrLv}Gf(Xtf$D#F{Me)RDs6q~mdO8ZN zt?I0LvGAf38@2Muo;HX{wHBv(!UxDFdtY3YZKgZ+Z=?|_%Gx~7!BB$Ir}9D986Joh zc3E^+Rqw8iYMUKEjh#Mg6~*kyNL#CfR5?Rd%W)%2gaJ2By3ptxcE6}<-_2PekC7XH z^JB#*Jm5yHrx``e<`c_v^GXA`+D4?9dscH&sa|PJe~C9zkO$XIHehgfe(94?9Ipq^>fhjs_of?W{_p>DULLpo`rr?kh%pXNPQUA zlDZZx+bj!$lW%5zfj^iyVe3V2851cXW_#>Ay z*3)?`?<&~EG?ckU<${Y$ph_LQ9w!pwcAHBTWLq0AkCD;7yL8XYc0cM@tfWe3vKt(K zgBeOI`mOOB?hn)GA?$lh9MSojwg|}N^a>#5wVqjrZ1}H>1}%$Ml~7?ZFD|=roPChk z!%uFKdh1XxKbpES9Md2tCtoY<7(CHnKSuDAA^xa`j{%s~F1^Z^vw!p?``flHMS#s6 z8WCat$_*bSz**QN|4kJSOrJBqJkA$B@*z5IVO{bq&e@qeoykZ{E(wcjWm`xiAnIS< zEw21fG}BO+b#?X^=s<_WeR}iwd^5S_;@;Ncm|hbn1qD&C(aF4_p6BGgUMmgnkTZGj z_QlJqAI>gv+izb$!2ztfx91+fM&12x;qcx24AxT(CHJEbaWs@PkBJRj>Xu54vO#+< zA#e?vNmvcM!&*Cl*s;hf*Qf#`!{qt z;2u&V(s2Hn;YfUMF&I>Lmo}C|U2T7kdLwq)p~23Q4@Aek?y`WvD$l8>#_vfhcrCC- zzWKE63dBYbca7ULl4`rdZo+=k)Lpv`eGjt0e zMvR=a+zaEwUmn-lXOxw}Jp&(-eeS~#BHQ50PueZ!WoG1DgvFiK4@1yMqeNIOp zefJvlMWA%~hkiHuep|G!i7GTx$YVbusGET3<@$j=l+QBJU#ISQs^_|js&~rC>sL_P z!Vg+(q)9 zeZ~zFTahi40-)~gg!b>qgITckT(HqLd3{YzK0Y=Y-?6!OS(|m85(VRXhpz4I#I>C( z7oasZjUp++;_^J@sExTtcM_85Y3Oxzi!pebr~e+i9sr+e7MdfO^)c8dnc2%Csepjb z5&`Y+gCx|q3J3e?8u^(C@-UL@s^Wc|+ov|{k6a&Wd_DV!a`{y^Li4z7S9x`Qv(Vck*}SLvL&zmJM~|;UOIWq7*qMF%29bj`pFjtCuzBcZ+MQ zp93vGomX2^<_!BYIglIMJ2SFGGu&T;7F}TxzIV7?5Srp3h`TVp?x9Y0Fs`YQWhvrs zoY|L>FWfGPLx_sdNj)JVFSxHHEPpECQMI7JhzIkQsq7W`M?mxC*5;~g1>gW2!cki_ z+vCn18%)7I#DA!hd<0gJ0pI4S>+0t5+sN#1lyMBe)qy5TVe`UDt|v|@$Z~A+YaQEF za!yD42&L9@C1E!VH=eYmpJHBNPT1D^F%-+Od3O!UcVT~ zaT`LA8e2m;7raG(01RBcv7yAMp`yHOB#s&Z3tSyrDT8mQgVrb8mBeh`ZE~D+rC7q)B~Kl2 zZYaTeYub9wd1&;_XVG`0zor*@>l)~D@vld}i56e*gLji9pQ)obisXrfecH;d__cN} zssZc_)aAp>g%RKjlOV350#QV*#oSU=TRb=a_F4$sNt&$|X9qoIWg(DLXUk+Xe zR}t=Gr$NZpt#8i9lY$i^@Y^d%HohVVHjEj9>&Vr99D#BQI>xuc*Qpz|Ych_b^enhI zYiU5D@Dp?!1#%qm48-^3d1iX4;};zor)MdhD}Ffes0u~>m4U1Ta@-`EEP@UPj8;02 zT|7n@aJmCGkivhvglL<)*YyV+Qu*!v;4J8oDHqzlEsVolNhA&V3U|F0v9Sd_l3 zbhz%^SK&`pEx(5O(8!$+j|S31*YxY{Y#3KYGug6)|RuJ?73|5?GFY5Cf{$W3sU*wG!wM6lKXeQyz_M1 z80_rAINgJa`W+4?2Kau)z>ZuM?{MzhjIl4IP}xru12DbKa$`5?yyeA*Xqi|lzfHw- z&J`W=$A!uLreC_mgHmUNs}Qb4#-U~zNl|8YOlTF&8AZ*e(@A`2( z#EOFK@m%M)-Ut7PVoGz(1jz9`c5my>SV})h$zI+|%8_DNG36bj3Uk^QNZ*qTjA?=M z#Vf1zq|6}~DdGVDs#%a|tY&9;kAnS{si}KkSK(@qI#LUw<|4t7M@x$dLiLZD&nx`| z;6&+~b6p%YC92oxSva`Sk7&eGJ(hIiFK6fAuR zV+VhaFwH`Wi7+HpKs{EZvgrM4n=T5!>VN8jDq1dkU@VS%L1CG4hMlw=0SdBK8trub zK%?3^WmvdEU9VLE=yeibULbnR&N4IX3--UHtWzEz_J`R%meEl~PfaZ^S0;AO%+$Sy zY#B40P2;{8M{EoDsv8;EB^^`qkJ(43=5KeXe8t03S@hXI2MeyLKmHBjTZsUJ91MCx zN73J02irTSt=I$fmkDe2y#X-)M=3o?I`IonK#EI&QV%rBe+x}n^MDJ~TjgiiPr?AJ zwaC?@1}G0Xc?Aud=dl16Uvz0&a1mH=;WKZTY>PF^EFG?mwgg4YigzNnWF z2gj=rK-a|e&3jYnTxv`d_ih#+WQ4ufnSrgvj9I}v-J?(c$EtM3ASLU$JV3ywvMjH> zd3JQ-4=xb!m*fxulX5%z*F608(C7cXE)npoOkihA2wsCaJ(xUL8_H{}0qw+_$|R1) zG^KsJF;IAeoU0SR^yCtdo-E-!*GyGoGu?pPXZvjs=7-2B*9Ti-&>848p$VgU$^d;) zVzYwvj=guka5SY)F`YkPngMVG(1~q%&O~O1Ez^Pw`#!&Z`JtSBTV|P^^F%uXONcbG zew`aIZg=zkAYvMwXXggjNIa(J7kNfP?fV>*7ol$P;x2Fl$jXHN0`Z@F2Mxx&KgL06 z*w(J#3@)$y>;HyyE|K3bn71XRrNf2B{^ivEX}Qp+@Iz0>S)(!|&+iw)auAXXSgp15 z$d#tI{RC`u6D%3i+5^LMg%SM%M}+%pGc-dnH=o&8SMN9U1XTF2v=}%lrM!A$>Q$N(#Pqx4`p5I!k&$uMS?4q-snt>kMBt>>aN6uE*?- zE;(=_=ErdLdQBA~E>QCnC@YBWk#Bs%hE84r1`#Fb!qGR)`rXM?cGA-hbLl&Y2`jKmu8QVFlJ53pvr|Z_d7i5)T?!?y6{OXZ~jDXraZmb z)*lLd+&0IwtXitX>7H= zXRK61_0tU7ljE*PVfby=WVMZw&uZg-gZn@V{(z&o-8}fTrOIoBBcC>(OW^^yw=3}` zbp^}10NI(ixRuTcu3o@O2MbxCdsHp2pfkF*?o#sFh^kBknvPDrD zu@$bSuI7$h_hh7{=f^)Bsw92w46jfn3NDQ?q0=IZirO=uXREzSiJRfIrSV)~5g!rW ztu%D%)tSb@857bIO`NN@-n+v!4Um(1&Y7b+Di8MLVKl0}FRMRVO?%k(6hFpm5lTvm zwbDZ7QnkoZ?$TX2Af5L}fmTFRn<{WM7gpfjUUu8CvFW_8-ZBitdgVWB@`}7115nRQ z)N(50K^q*}SF$0~HRfkiy$ph-u$$E%sVAC79j%%|2ele3FMw^QM!5 zQeo^o@o5+=SY1WWR52O-l!29#8_m>y(#q=e)S}z;aaW(Qg58i3rGOfq5#I7;yEn{? z6fM)w2v~WQuW&_8O|=|ujEgEi>_iii^2n)a*+8ip=k(fkvqPQ9Sf9bl%Rsks;C+xE z@N*1icCn_g{NxpxCtzK@XThGGzAj?ukut#VG>2)mm-Qvt%RRYx4F6%Z|& z$lazaJ;au8LGba+=2T<^%H(rZGOg1LA}v{0NB#DEo%^V&Zm#8z;JLD5c5dqVCD+0aa8t~CNqW2qAe}m=r6~JDym)V4Ze7WxON5U6)XkCjCGq-u_PpD_6Uz^ z4r0-439~86Gh?6~B}58R5*hk`?keCIPD<$v9lyZ6=D4rtPj@lWjYl?8EKeN_MIu;I zo>Us#0)~HC{Ru!0tx{tW%ssw8E%SciMBx2bPt6)6!F^vk{TB1K`dmJq$GlBv<4+EJ zd_Y5p?`~@B1#e(R)h#0^%u2$)C*3kN+s9)=$&-#MApT+esFHf#Xbe8-Fl@c>D7CL3 z$?;S^?x}g~;|A18g}#?<8LMwmNtqTjmI>|ifGGH=_0kgYyX6x5O!SmdFv8@#Kc&w? z9k62|O@)?vW(W8Tz2}Mxmd;O)f`PKDz*R^TbV!H6a6+Up-;$T` z-a&xkGT-gOwugmnhhy#CD>m0rVsn-p_|Ym}7rpp148A&^Gk^DEw6az9UsYL-k)B-1 zoay`{{K9nKtBe8KjEmhR40ZNM7R3x+X>9XZEX2q!`)qHnhN1Xr!^;3H&$`?BW_k5X z?Fgi0SB8~3I!u~{Owb6_9#>tVKU7z-sWX4C9_U0bjLl84CvFPebBs7LEd~tm_1HDm z!G#&8cniwV=^S)9KqeYq5`V7vY+Ig8KZA0La+iq8``~qBV`zG-S@h;WVU49;tohK? z_)f~9QF3}>c70zBbC(O-Hv1CQ695>7#lFb=!|%9f=Hp^80lC%y-O*9pCotaFJhLb& z63j0=EbH(0Q4y%`GZ(=KgFl`x{yTCUKQV~$B0Wy2wY~mNqBj`TbqRY zpg%PswRJK!T{}ut(Qm?&3sIOIW{?vyi2-`jbCw}?a*c?J(Y?sSd#myxpEcdw9%$X> z44gN6AbXWgUaIVaW4052StCR^#$`mROWfZetWt9Q_n ztZP)O^usF_Y$h$#1uv&OO(`L+iHb`P^kJ5J<2U8d&=DyD{yu_ts_x;B&vH1yB7IzJ z?jgUwHbDd4#=pek;TTVCMt*ksA$F&~P7H7Td>8yynW-u+%|QQ9mKCubT4Gy50}kgU zTph0qb~rnY07}a+dw>9_Zz2p))aMODvAw5iZvY7)>K_o+G2m7=vsH{ zT6fWH+EoFHl9KI_ZXn&7i2=ofNzQrFJFTA-uig8>WRWXH%q1!- zE29BXt1hMldJASbby2G8*XjTpDNtW~HXpJz-r^YrY1p)~;t>>{p5wA21Q5SMAE|b{ zF6dA|tx>Rq`g}qvs-NtYW`~A%etvvdHZMgD8>EREU87#M+KFe?)X}(yk!f|=ZX~r< zIe!h76xX%;9(JSRj>3%NkJ3S#^Z;_YF%{<4Z*6J4;)&u~gj<)CmV|?OJ3>V?6uZOH zWIDy-CpD8R8d{+`6_X;q?R`L8Vj@z=V~;Kv95ZnGIvFlEaBf;F`{mZ8f&r4vlTQvGqGH!0NDyHnxdSf zp_GqZ@PH@Wqz?FqZJc7^H^iMg-b|WwA0Q*>IP`6ikv^nu=qWRkiX6S#8JQbh9Fh#M zDx*veUF|fdP>i9cu~!ORe|r9_Ppx|Csg4^L&L}S(t$2?F7I;X!0f0ULkQLU8N{UCv ziBEK0wJO+}Y3R#MT3a{kv&6FWSL>JFp12rC*5OvnI%j;<+ZBLXSMGgCU2QlFeu;XF z(r35t%GGB8O*=?TOr977loH62wimLWEi7&F2&MM1zT=fGz8X@n#MnG?m-a}uacpXA zBmUi=VX+iC9!=YwAt{|tRyr|GHhWvDTK}u4@Y^>X zIXtwt^00#>S6zuu*DQ)(31#V5SkaoE6WSdr(;54?y}e_H^Cl5vIfD|BwI~y9RySV?3GzB_2tf7F68)G0_xpN!GuyqAVXwtN4sZ z#M;Q%a3rt>;Z;eaf5r|Y6a`U&JPUybLSxi_eFf-|2rK`LFMrpo{%M6xu{OXjC(Vv0 z;;Zpbtf!}^y!%)zI@~S%A_uPS(L+KHJ;EE@^IAb z@Yie_F1LZ`pTh%_3TyW=$(A?I94{^vb{kFS4Qm@8#fx4HIL2IObRH~k%>_LJdG zx5eB*8y%~$Q8t9fp*t&D2KUM*`&(4-o%!n*YzyPSVg~FRs+mOTgg}yEX6e`97BhP! z^J5?~&^Ss^Uz{7UZ78H&KHAO~(7$^RNVz$%(f`P5kY)8eAH`X)T7*N(X3@IfN#` zQoJ6QRmHY*vXG=UN5U+(v)l5gD-L`xlbp*7L)UQ92Q293!OxG2h_69GZ`W_En!6ux zruMpfz(2^*@05*}dZe;Kmtgj0>9*~3y75=zyA!*IiAls76JHNZz?rK?x50gQ_!k$| zfy}=h1VIF{q2F6QUMI58vwN5UdGRLViOp6KN{FNYIl=W0h7J+;U7M-k z=c?%-3B+?e!y}&c8#Cq*<;kUSyyT^A_xflByZf0gO(ZCjuZ~-j6)ceg0$G-QFu6rK zW#;da1bv=VsPg-Wk#A>jnYvIqF2p$8z6Api21$QTqc>FIG}!@oQ7u>Q-Y4U zY@(iafsAt^`RQS79$3#2YvY~6M6ltJkrZgdB(%SRgBjhd`Wk?%cB{Qi0Laiu`)jbg zq+nv$cWksHER-luKCdK=w}$?r;gaAjO+bKFcS>IBYZm zqDgCf7ZVySp8~YojMic>Hrfm1iPQ5M9ajy-GbVStu3c&dhK>u7gt%)^s(|mR>3%CI za_^Pj<4r*L*GUlPe`Vcb^K}(j#UQ8YHJPS}oZIBMc-lp|F%d{V{Vn!|Uu~V+#qAFR zpY-^B2X4gbXbtOt4`%_xJ;ER%LEEESKfMP?5&OfZ(?{K{pN%wLyn>~Z zprL^G*S}Cc&$%u4T_UK3dWR!-fw4eVw4Wz^5vbf2ocI(ruZ}>c%DNf9!GJD}aMLPt z8joTP0t2qXa^v^pDuBxrc=Q@IDxBTyak0neR%y(&2;UOm8n}J3))2Ryx=Kj)BzYz^6REgjqkZd;&915Du8VIoDdDNtlrZ}n5z`ARnwM7&)A1nwK{3W|NB({P18c$!kWfLq=S&Y=Xu z^n{p*I;4LVs1E!|@cyzOTL00d)#uO<>x9z0KgvGG z|JZs{=kM(*zc8(q2dvMPZZKk9oa;YxD~5Mf^xhB8)Z*WdE7?Af>$U{dpI_tp74w_2P4Zdk_kA4EGZ>E6+k zIW1&m{W|95!SQc60F(GL5&}lmukTb2PyF$06J!pWs<7F#zIL74WT~M9c6~hu4jzr7 zE}t^+!c1(9kEOdLf^x6`uXOPW{u{VuhL|lgDx9TnXgQp1K#<c+Nxj1nVLGW`y*k@_GCIBUQ`8neb0X$NotT2zHnQetoP9EfDqNL zfG2S7JW2b>O>ad481nO8XZGkar$%qBIhG}2#lG2~SW&B9iAu=8_?;J?gfu#v&s=nS zcRts1%uxQ6ms_;d$1yCHiztkz6y=@UNe*3~DM$xyq;;N!l=Jc94pe_tUNW9R;6a$# zZ)l+ei3+4s4}vV|g~F8ZG5=A%+aQrH;eaIDmoUd77F@Gc{G}9XpxR%j|z16y$f0J%u+2z|)?c!cCZ! z`@>C|N_jMYSV>H=G;~Dp8%0f@7xfFyQ^=*LI65kws=>p0jrWEdHEq*D!pt7mZh=~@ z*cG;A6K{G;AST?|>Iy|nr>XELVW02LCBLJuD3Ef$M|<8*N=oS-0P0sfe`Cc1lvxcM z&BoS$pOA0QmSPG(>Ygw>Z`xK4vS0z)$QCdMf@!YwVnH4}nbz9?mV>-idMg%1Y0} zjc!#Z1tiNDlr7?;r#vZH2IX*maG>nKyg_$s*&`6!YTTwnW zaTj<{bbl|OzJc^_aH|TGeNhL3Q`FRMG)wE2nt7h3gupF=?|=Rq z3U2J9*ToY9z(;FlgM1APkT*65^^r49uu+7_GuA1WLf}Gt>4hE@hAUV?PFC(G#75s6 zQUJ&yo#;tk@tT&GVb&ce0<;vp-d84uu;g6<-d zxJ#uSQOkPvlNr+mp3T5~ikE0Jh|qPskr=cG)vrD0p?fWm>nP5dy*t+iT$`poZ|cnM zGVqpP>I~=R@>v;(X~NDiDp)4BI@E#oyZ}qlJFtNu?9=o@K;e);uyu*>`;z?mHdbE) z-oUZY7+#eQ#Oh2vs*P1*M{!!Vt2JobK5EgiCQ(JTja^rbt$jVs@=4f>2y}JLO@RR2 zx_S{#`N?z6v4Q2V{FN1OmPqO-`ZOWbGL>~uB)K+svS-6NNT^|%B*XTi6h2_%UpM)) zTgm^m{NBs~%gWDZe{kqd&)$(XNdnx=2jsl>w;Yo6JHsi;NFphv$w(A%n`6d5h(S!m z2Q?qOz6=!w#TsF4soULpfzRo`m%zEr;p67i>@A(}(E5m8p_CI^n%{<&d4ffeFRu+hiv1G2b*6 z4jX=SjpZZygKKb$9-B63XdED8jndSx7{u|9lqmF=rK^Rtvh$#SLr7G}AYSGL;-FS* zq@hBlbpo~}H3u){PuH*Gsl)5~15VB?(uHlpji4tfEk;|p020E&4PAWS0Q&hkZ<$Ev+~DnMM#-{RacsGLMDjFDIh?4CiB7SUp zl&DpAj&}jl(F({Ph7+D-+}cS4&i5>!v7H{0G?A%mCAmU067n{P9NH(R$m@4j!#ic; zdw{w+0cHb3IQShfvm?3oKENXbWQ89VmGCDxMEPwc0!bHrqemOipYj5pmQlGZpt zB#nD|FY+x0it5pF$}5t)Bf1E?hIIl+1SSD8GJM5 zfxAnZ#4fydWi5@F8?hy6u7KdP^@#0G7F#t&?c*vM2Cs2JNi5} zjFLQ@bs&%%DfhmP;wLHq7FWgw2QBc9 z;yPxeJhvs_SkjMu^9uffCpzd=AZXi5_HhX@@ufg%M~>QjiWj?>OA2Xu@8o)dGn!)a z)@libf#wgg5W0%@53U2G2-sWzzYL5M<>h6Q$t>qruLL~EYHc~lp_|&Rq{RiftrkC= zhLnH-uGTxEGUgs7XlOj;W|swL-+;ne3J8c}YaRnH9!l7;*~)8X8H?Ag37BM64MB}v z_|pY!7ufN?3OpsBJDgFi)3e~&6^tS1MFD+XWVF75-KXUZP|jttIQHnefUov|fpqgS zqs0m;I}Sj~EzkM|ZgN^GCm*f-FLd_jf#&TK!CVrkR)q{dQ5t=H{wGQveSmpL)?T}lrrtf^j$-NEx~O`Ff& zHStFhHHMOb5Zj5dpq^%bAlb|fixhrFO6l{47Pm6r&MKm5ZEpVUfOys6#F^cG&=)9j zZ& z$bDekdcKUlLwK3F>+imqqXXNK!<_TywN6dgeNs)WJ1wyx9do0k8G}oPOV=XFCrTIP z_dqY4GQ;V-fn|8g%ufB|FE;SUn8<-54K3}})Id>kDCM_&IM`Oe$6$s1@~%OXd`>cP z(A3i8_1XSWu*sw&u>L5Z{|K^Jt}raKKZ1jwlNr|@*!wC>jM=%)swoAL0%NJOy3_Fz z2u!oAI_Qq%VZh-){!Okt{u}Yo!RrvBS8J?}rLT!+SjJyWJW_O>Np zD6I?P(+$U+@>=)5gymk0=2|HF6znS+sPO(BY0KeoY)%?5k7DqSmp&y!E@Ld>C=>*I z2W{1C(3sgsa5l3q_Poz%g%zpbd&u_|Tfj{E`Tls=1;!FY(^ia+riRwtL5h96?y1~s z$3&jxaw!mB%EyUv0%f@sz0DEilL3%DOAAQl?tBWj4q5^=QU?*=-Yy%3w+AUuVMjLzl`ALw}lbCuVqidEBiK=GW}ihQ7< z)qq9&V*W3F&?@b>1fZHLa!Ij@y{c&`mhlcLspo)j{+)aV2G*I))}hcLr;aPo(rq(k zjm-_jfsY`VyF6gaMeHm}fNImfzdgt@6KD4Z=+bV;yGYao&zx0+_Ry$z)VTD};c=8l zE(ff5c4H>v!2L^q>ulo_4GpTJWdYj;M^s|~TyTz7HMpjxQp{4ssSqSorpcoUq^O$F zC!?N&z&X4=6=+)}7S_-pneS~PMMK@frOZJ(XJFzyIHUxs)OPEEd(EO|HeY(aKi~ff zudrRoIWiHR&->JNqi^Kc7cWk=ZF^8MT$n{q3yzL4cFAA!@GrYd0IeRnG`Yx1bh@mo zE!8{+w+I3!U?`q_838BQ$&3VD&~#v`bSngaFF4&L$l^LU$BpayD`S}QGxeUe#HPck zu>Wsk$VW#|xUWpYqO{5k^UYyeMR~OneT%N^+5I5(KT^o%q~(>Uga`%?0Wq z{3A+AN`{NYpWIjxjpm?}7;b&ypNG!$Z34i-X{h#9Tib;bGU@2hp3_?)LU?Gkn+rPLP~H<(Ln&F5EvFqgt>* zc!fFE*hLfnUAzvjD*&NLeX{Qe&NB;hOFJzE-g;N6lQ5TEtWHw{NR)r?7{4WBN-r_E< zEt+s}4QP(b0QQ~kvsV=p>7v7`c%~4g>?OFie2xB&k2Kgqf&heP{Uht4UXyQ% zR;h0B#Drd*&7d4$F0|}Q8#C_%qlob*E;DoX;+lKK(az z+l<@s?5~Zg3&Z!r-EI>Eo79YRS$!0{LC(fDr26Wd9-NS{idGoCQJ8KI8CzdAviksX z-`Q?^p+f{1qaAMPNC@ zogQz^NQ1&R>N5ZCHu21m8Fll>1Is{DpjRjNSyqJL%C8K={W@hjk1{tCS%wzR4^zPj zZf(`)_+vUSpoXVL3Wze{0#@<63a^24cYkQ~2bl%11158<%c!AvvClKOA zY@pD?k@%VVo?1RET~mh;G@0ex%hc|l+Z5feB!KT2dIwPJ~Y+1yA6xqaor@v80lApRh-QP|)^cQq=*{S5OT* zS{(qLTG@@aQj2H2#)FN-)0FN}b?ZkyZWDf~cn7+XgswsbZ&+ zs^$6Z^wh3trlxDwl-mxpdtcQ+JqWg+M6rQo3q@B7IV=)O;rUUm;G%PWNAa|MZo;?1 zKupakI0I+g?9}#AG0g-Slrf`5^R?V=#pFN7U-13L`~W?qDJX=iOCKyof)WIg3siR6 z!u#))j#llVHITqd#l5>nr+9o7oZIvN*n118sMhykbkrjr1&@J*q=K|`NP`Lv-64&1 zBi&)qA>APe+_uZ79-{=3{^{xM{@2y z+)nQ_u~OBb5r9?5rSQqHV@}%rE9OewFaCP<5F#%gL)NM4k?X>*;+#6Gk!JPM?1wEy{U)4;k@+5a8vBk~HI2X*g@58_ zW2QVvw)d`o;$aT01SVcgj(A~ryAv3=!+slWF-Qb0CMA2+X&-mMda!yo+b zT%Y{x`)eWBtY`aBkZEBPW4>L5)M>MQ3p*6Ux!N+S>adZRwLqU3_!Ch<5gZ^PNvG3% zR$`F=V%AW8NO5VKWK8hzp1;3FRxz$fs|R^Q1Taf1$jeWoeSWM__nyrm|dOgP*Y5>E(6YL zkBAhvd8cVA)Lr)W?HmnP)0MH_-OPgn7#IawD#$|+WJUoAQy|&Xh4Udu)b;{saj@^1 z;J(pKg%HjLaBrW>1X2H0`6T1YAI5@H<9I z;3xXZygGB5!X;Z28PE$QR*Y@RM&oiDj8}79jH!3Dnu`GJjqwL7GDEpMS721Qy{alN zUaY>WXNe1{n7G%a>8R)4dXMhXMozY2`phNqRlI&kx?s}SKq?JLUjhD5rOEr4NF1o! zeFU`Tr$|#+VjakR_d53-pLy6lkofMlHkV;*I*qvQ3YLmS$`TOLtBjfDvj;F&O;AIo z4eV9Elc#FDPt?DeJYX=481CgulT)6q?alN#eFg1FESE|EZx6-N6&sr!JSt5AGT_bq z>SaZ`&Mle{ zp5oP|fydQ+KQX>e%4U_Aw!2lwr`T2RPrcP;0g*FtQ6Dq2bJZ&km+V`Yrn6MbxR1&e#C1t@8eg3AHZwan6!)V4BA3T zExO2QRA@Uoy18l9>QR?hKMwm?lRFr;UxwZy8z(nUu zrj5jxdc3f^fKFUwttVIJkyv)!I+w_+GFxa#x;U9dK|&OO4CO#J?gpbgfS?-yL9-dO zDt2xJX-*3gM+5~Fd4E2ST=wQD45x1gLS!h=e}QQ34xo4JVomoSU^9OQ{N8|Z_&ta$ z0JzyETD{WLZX4{l_ z28v{lk|ni^MNt`oz{?4XQs6xf&8)2CNf>K)13jIB`ok*VK-=4p6H{c}iIy{5B@Vej z*_raa(3FDM)yvG)@-a4i;U2sxjX$zd-~gjQn8ckDaZOd}-8G9%zVmY-h6RIQX!Vpr}{9`V7GH zDS*g%ZZib8Lr6FtUU1GeOVv_Eg4YA7a8iu_W;i!kUovLfFb|gy}G*D ziMv3osbWBBA7!(vd+(?i1@aVLZH}fL$OvqbE%V&RAW)AR-J8FfZwmaMkVPUv3v5&d z6?ZdRY8Kwz+c3?DTfWaGr!Egv*wG2YgFDBG{6TK&bN_-wFA^|~fwu@X{MC~APGUU) z&H!EN%*tr?EhnI+a{+51XQ=xI*z)RbY?vE|gA8W{&G^M8Yjr~K%jG~5aHuGBkw6HD zCnM3DVYwW$>u;xk%>c^40%AcQe8I%I| zaI;fH+@kQc@Tzpv>lw{Jo2Zc=LVxGDZy`)GACfh9uT-&@cGcFH7=* zz#L5mA@AEzlF5#rbq#oGh88}CQ6?660yF@(TMAUMzo#=W8!;>(n3KBcsD~fDhNX~U z^!P=s;R&7og!eC;4!JeE=41d%!^-e=3+&)98R`uVrEa*Ka#kOHBH>)4T=i| z49DhKkP-j4;Krk|c##0+JRT^+@3yKrt=I0$8HrKR(o_xg2RK;hf-_XDmtECE;oI7ne0FiwC^b)Gc)T8L6(q7{2t zcc&_(lqt7>%wcLOVu^({p^dq*Ywrih!3!`fD~n2Hr9f3jTch{MhTi!-5FYB6I8`FlsiJg$cTzqJ8y$^~v==nhNWdE_9_oDl3i z7)Nr$#zl}R3!}NNSP}uUv0Tu938#8xDYn>$>Ihs7vws|&fsPion^1a1t_P3zL9VvP z7?&PyeBL2P9Wnl7)|m$9y35(e<8ioCt|!p*c7xo@cUy;T4#=Qg_k^4pw1$@6>H#gw z`pmAm2h|NIF;ONP4qm)}y>LF=-*{n7vQFQYEb!vDu$+o#%{%4t>8f23^qC#uZcTEv zAOnpcTf}2pdY*=ZTdg9h}Dtm>Sq zmQ?&zXDaZn>F-NsH_VRB$6jGa(y&1#pWZ#uhNsp7|2 z=0GLZ6}fKZ*wZmKF{*c;c%-dW*xxnR z@KA&(5_6XFlCD)>_g+O+17|V(RRW=Q(#NLqZvJ;rFeh}q4*JcB>iE_r#9i}prq;`q zZ_(I;LF#q6H7g{X6F8c)pSQR2z1r$na8svnZ7V;9GiEq9cJ!J&NUI2yB)Ih+I1nFN z=#xr(f7ZzjDxzkL~o#68s089(5`HXmLd3Yhgn3hPQAp z%XLvc9gi6PnhKJ9A6-co@)S;_YTybiVfn~X$o$OKBK|6`O@L9B8tNgDFL5=MOCA9F zWTV}i%246pOg5}cqfXU+9tpB*4boHf!;@y=*AHG@`)s(%D5LT;H4KTEnXwaRRYwzuQ^cLePo>Xa#C#Zl3lx_LFeeAHN z{k4Mr3N7*Bx7edf17$&)z(2)%i}oA+y>?X?Ka z?}uS|L#Y+LI1P$&ShJMDDWEDuZ6Oam#{KMK!Tzrmij^>zO*4 zl~5}z1%N2atPlv2*viF~(zi_7lAF0D&X)SR_}Ry^hJdk`yD*iW4F^zJCE&I*G(8O0R_WMsiYvWb7Q6JR*E0 zA*D@s8P?b@N8gt`R_4Qi7Zy|y{Xeb%`-g6AT@}O65R{kkl6ewxA*)oH?Y#}-jH&63 zFbd{pkiyN3V{8bxc~O?S(XjGmA+Dt5^v1U;h`itgQRh3)qi#Ct60bBpKl6hA6!h|t z=07?D{|4CGrk9FRzC34DD`8LpXo}JDgL$z<16xbG;wlUKN)RqXlnyLpKnp@d>*R;3 zZd6yqml~Nz$7uC*j&HRu4IUQAI7LfO|CPA8xVtB+Zxn=zSs;c5b{aG3F$eCe~i48jd878HBF)7f@h=Q;cM+brPR z<%5Psyfev>8C01=Pwy=EXnkD^_zR(|%JfOjBlL4l7}%r?!Z)1{qNDTjI57h;3j?K3 z-v4m(S5AbpCck^>7Y-gV6usRbQ_d|c7yaBeN>gh%hn8xZm5$%MmQj^S`#%>ec!5Qn z!eGoo>m>6JXyK0IiVxXoOYCF!2a6t^_*U0sN_wi_fOv=FE9nJKU50z>Qwy;Vb>@Ig zEC&gL!t(lbjo?5X9y=24~#hUjlthb>-Jv@541p* zKD_0$N3v`2*!9474m&kSODvolWRHD{IdR9CoS2mEciixYl}{9Yo{GF3&#J=tst&1W zv@|+&d%1+NUXp-(3k;SPICodw94DrSSEzt2wr|cD_TSv9PDTpY;*jqxUJtm9)2z|_ zWfMD8gMx;~izw?`ceR=p(dFJCBJ0hQDw@O$@lM`&{i--`)T{jj(Ig`{djy{|Vfm{|!v(ev^7lHa;?*^03U@RTH-+ggjPCJR+=Zsfu_c;6b zYldw)kyP#(BM%v6WdSRw=?I_QQ$-IJ3d7%Q&`>rt@&w!+nbJQgY}Jo!s@&f}7Q9$; z(GMr@e=_cO z{>J)yjHfcyk4L98?$`KW225k+It^0{wj6@pY3D(f%xI8RI*6wSoV~<~CtRaSCPwht zmy6UY!TLs?_iF9T^c<0&<;++P`h;eJbf2AuwS7SQ)27rvuPM9L%Q)PYU7Zb9u;D(i zzk_7ew?=E7qojcsTPP@S^RBdwDL^k@$Ls_C?gbsbcanbpaHBiSZ>w*Z6*Mj?CcE_(}oOdFBF7y1ubHYGJdu8 zFnG)K(Z2!6W|jItwK*}Yp1okT+Yoodt#9y>@jfIhZ8{go0M>kVP1XaXz#i8GJbJ~T zC`PlRGI?Vdw!Z0|lL37AcL9LoyNSZWGySSN2BlzT8%|+tWv^MoQY)QL+CEAz0@03D=y^HfB+a#m-4FpCHna98FVx zK=YxhELx^jBGZ!%8VaVLdEV+EsDR6@u`MA#u=0WmUs~>PC%yyTy`}~&igKxQ6*3Scr4kPc=dOPgLNe4WSy0cf$3Npq28CrF zTeWn75)WoTAppGxuKxmhgl`Yjt(f!&a|1V)0l*~|msx($@wE(08Ue=%?rp`&YTRIPqBF+wJ2*;yIc{tv)7t7mF^&ug@ zH3lu%Rt#QT<@(ViU`3q`xIW2GdQ^Jo$$AtQvmIrc15H2m`xEB5S1L0e+J$)YuD|2w zAT6*8k$^%-b1Tz~milA@oDF&GW5Y%+!wkiH!?1q5MD|SUc3Ubb9N-+ZC^hG0dnDN( z4ZG*vziOi%PlZJZ_~|pUD3;P`6kiMjMpEq?Ag6X55pFtI(Qwic!uI=Y>1wk`TbXH3 zNx9Wev1nWf`%Q(%R#cA%zD0e{|26ie+p{OD^ZTEmo4`D(HIS0&sA6I8%0>nin*+&y z_Al?w^$$z1a^=T#Jh78QEzp8mPQt9^4R{OA`Z9hp@Df>2W^Pi#7qW?D=t-7lvSH&! zH{%ZWk3pF&pi7hIUkbwGn;=64V@aWH1rz;5DNvDzIf&Q+PK+Vtk@gQS8!BxReO;abY% zD)>O=Ji5NP|JtSJH5?9o_7`979tNM(A~<>I`eN{5h@3(co(USZ)IP7 z-$E>>c89Xxw18uwpq!upSvGN;#T?X}7*e|IQ!gQ7QqBSx=b$RzO!S@%oh60Gg|pgR zzYY2~UC8qq5W4DZea2z6dG*Epqw6=HG>jSkhFgWj*y^cIRNHoctZi+vsG@2)$e5Zh zS35Vnily*|8z&?rsYbp3H?S&%bDm84w?F(Tse!YU`j%qftWwcS8WrcR0!<4imY9;c z0Ubaf5GQq-pV@uojG6zf0Tu^age*`uqC4b*$+xfjL+Z(dIW=8S5ru1_6p(gc)?mW$ zK6&L1_n+A4x1j)Q12lQJ6|1E$C6WF*r2L`+R{BhI7rHgS_#V#_G~>?jTPmfqQSb*3 zPfAS*4?l`W5AA(Ffi#825C}q6e5OsVI?$CoE(>-DjrJ(s*!4*sL(1tWR{k`K@A{zHOaJudWrti)9RbuE z1f_AVJAl%ISJJZ49q2%vG&1W};8J)p?7!*%a4ul3cR@*oTDxWp2Rb0Pb$53|jVJ;6 zfm%u(v%|01P;t}2M{x2nVh9mE@!WM9P`80@RJu)sq(S)d5j^C-F0U7#$?E^_00OgLk%sFav8X zE16KX%u1lSxMB#6m2AVDDu%X5hT@JgDB$^?-$7i683+-&@k2afXS=`m+wQ|-|A$1a z=T9F5n&nWNC-h--eV{(0X{CN9r~(1R9x~!E%sL(ZuYdP!%da#Kyqzv+Ss;UF)0}}< z;_vxJ&fw!YtVJNOjL+@~NX>CWdyBn$F{%?vLUMfJ#q#`$2t0e|*N3Ewe*%}Y@A>{j zu+F~yuKx$Rc=j!9?@#-8_O*M$pZMjouUDA=1VLwCyZ)&{>e;uST7TP$v%6;>w*Qrf z{p|MXhyU+PdYf-^iL0r(P>gt!2T$AzztIa}&jn-?O=mftZQj0~CON)O} zAr$51ut|IZBV|C0Is zu~9PLlX9_lMqTZCiIZlZcFLON5lIs&#=0oo01g|!t_!CY8O=6B&YoKvaD1OL1OYvT z>;Av|YW#OW>W@qOe`cdIQDXTQU>Ba$VWPnp{SmBS-D$wdh{Ur+rMCm=BX;2Wfj#FdA?A$xRGaM<8jBwcI|TYw{u=% zb@uf303^> zeme%4aPECijf7cSO@nAQL(47Sj#;mcj;d>5sTrhFWYk7@Y_zV87@xbKUchpjH5plZ zu=BX}BSc6T+H{$sW(?+bSeqv-FwsLHq~`wUR7S<%gpO1`DeMBjq)!x6MgZjz<+^?& zP$M)}*v7h4Zy<&0qR53?gWzQ>P`lxk@{YZe&OoPHZqzX^rP(HO>!_MKG-O7x+$db{ z;9$C5YrD^kAT#RQU}3lplNwzVo1x5$FR)rR2UYQiEgHS^FtoBwqKbGhV_?<-OA~R5 zVl{=R>1lkUEyl~$Lq)L2!4`djy`BB+l#&rbj&tX78?m)YlXVI!Q-<}64j61gL(+$w z!aq*R{T|fJtygEwe4AT(`9lm2e-RAsW59Uq16fRyw8(L($pd5hHeQOgHh`vgvNm_7 z=$45e7>UV+Dngq8t~Y6?=o+`6tXz}5a|AESx{Tite6@qHR_VP+qn(+h{Zw8a44{@x zS5+Kg9F1VTbqAD2T;@Eo)%Fsb{$4vFzzWPZN&!ArVcodIRi5D6Sgurd6Hp=PsXkyO$$H>cwcvd^cU z+wrvuj~`i##^j-71(Z#aDM~E1&-r5`Yckx=N3d|}=rtIu_Dtl!?TBB?E-Y6IF*+B9Oh?JO{|-p^S!d;8l2)$3dVme)IWrn>=x za|S9A#x2UuMxo@Y(GYQDi2S*9V$x+uiL=`&B$1Zsn2hf7P7bP1L5D21iEhG#d;^Qo z@u4H%g&~JX@M*q>(0@}*M{D=g_Z>j z(%H#=KH9*{)U{zz9!oyI!qyOwo&Em4c5SWxmxB3@`vdywp%U<&?R-i?#?0rR!8ULu(w;`Lg)E-4CW>Q`3>A*G4-hqd|v)ld+7_%CqD1U~O%+T-1sd zxq2p}8A-FWfB2PNguE4C{Q27vw9qJEnr%vjHsW2xruGes+VB8yG`Vx8x#t&heWOT7 zhMl=@hRI6@-=~qH1|uG8&|wPV?CDx8!}1NUnUU_kDD>AlywMn^cBSE&Ma5(dbFT0M zJAuyOa_t2xeH@0{F#hEfWzHm2fZA{_mlMh`Na)^`w~&0|uC+>d2kIUS;G0uRVT+G6 z=@aX6I-3O{9j2)BknNtb%6iS)Dv0@;S2p3vdB27%kUCSsnB zYwcwuhlLT;J?O~f6vAO7V;yVsUT=!m%G4qZ4Ha6zQezm+_Dl&88qV0NDKXt%cKxc7 z1n3eh!~MYIsjhqlDp(Or+a-zTp93S8B4S=?cR3i0$7dX;{yfUNbB%d^h9TrzrgtKn;|fvsPFFOA}h+bu4&4?Iv?ZNODf>P8-kSTpoz^u;=w&sd^j z<;(PzfoWPXhm80}(Cp02I2a<#g+4?AKGzpS6u~4OFNK*`HP*n}{1?W3GBPq$Pop|! zeMg5`Z(0o3SleNaFGx4%C#H;Ig-O|GjGJ0)@6fheZ^aYkXeg93v?y6B6Q@JeD3R|> zq*=LV?mC;LC1zt2*rPWvn3ViODkXr>Ta0rUSr49Er4OkWC`;ww#QR6E?5BO;R^{$h zb8nwjA6_vu3;|gRF&~=NMWtDrGFGgs56lBE9G0^wZxJqz1KbeUn9^af{@Epe+4CCG z+uzfvh(bvj&%APhRa!=-133#?2Po%k1-R?IetaDdSw7H|Q&`_SKW@E-YVnPfqy&kY zU}&$!$T4S2dW2ZJ;d2Js0`wz|6`OD9y_qF>QvmkA03V`p3SUa8-#fvhzFFK$NK z&bK1OhEW~9`rfMjTBCY5{PK&>i51!R4^XVjezMc_i``Y2^YdDVfxR_VS;PTpPMZQM z!`|O?m|Q|{!f>xJ5zZQnC=+|;jox&sUehEv_&POXU@(h15D*rwm`*kKo{n`^AU-Pe znpiD@eMY0*igXTMZbuw$p|)2d_=qW#qn(N$boSt7l=OHR_yn)|Pzr|&3L6><7&3{7 zgxnw_gVz4RX8^rpsGDg*HUi{fK4O{UD2<$)8&M1BI-}dciZ#$AxYPbZ%PP=O+WVR{ zdPC!&A2IgA|Js(3IsCCGL8-Yp^m7lc_++waPADMPPse6*ygKlHV6Y5d0xoP@bham8 z#=yuwpe`Kz@h&ODY%fS=WLoU6yd(n7QdLA1S&N$OllTw_7#XC_sGvQX=v2ZjjRT~c zkK1;K{azj-7TSH@iF_n3Zk*6}N_77!AZb-|lZo9#SU+0nob1Qn37&!^%jUaEK zbkdMHFCl%6PwUnrdj*QM^Xlsz6)k_EA)skgD^~JUtyYiv?Dpif7(Ib&ixL={{A|P* zB?(TZCQ(wmO@@^!9V{jwY)B#^LVQSs4rBP1${Zw|O4^Cq&g(*LLKCsJf{*+IQ0v$Q zdN7?RkU!sJ;#lAZ%`J6C-CLTy%4g1!+J5lOrz- zwsZq4&tFmPAV~{;4lS`jhlzK+0a07MKWaCg3n%^tUJ-!H8e6jz+g4-45+fRd>+MGy z57;2WnV$@Ss+5lRscZ?GS;lUP!spxWsIJArQN0E5LTv!(Na{Me@pP@5%bc%BlzZ$w z(Gb*U#XU9WnK1J}RJXP-NWl30c3l4ViS3mIEIjQ^LeBr)Qqw}7hi(oc&`s`OeL#PCg;aQf5j>Gj2!(U=}DwxDB!=uP()A{k9?yVY^c|{~D z921%x#tmi)3I9Uu1iV(RjUimXeu5E#t4;DuYWmjU_3Z2TWP~aaef7jDyPO-lncMfO zrw*gT`Ffom01MOx0A^^#kGxmRZ%vYqxrJ{$JCe^yA~ZDg7S~ONzi8tM8NyqXaKUn- zW;U-{^bW{dESGtXJzYa-fog1MQT-ulNF`s%qfr2?Ol^Bq`c2B9DuXOd!NG+-O zNG_{zCi28lN>Os{+6uCKt&w2+K>)+WTx_+O{>EeZW&8Pg2bu&X>;xIsnSG4s+|Ow} z6_ghvQp60Y>#13&55!>-CsLF>T4ERm!x7WTxbN`LCHZ3my0e%rhWMC@6Lnc1uJ!l>2~)QVCnPzTiD2O<;8UxK_u<=t%Aoa`M0|@1U zWOU+FwLCNkT!zz;zG_)sE@PVuWaFOP%qK-Kf zu{3^RAjwEbs&|HlTJM+rzAl=_s)0{$!^FtTE2>GusHJYg+^a(7W@c=~l^z`HKTdbi z;g8vvx+Mz{a3Bl`4e?c?qA*5IDWd!Nu1en;=NFKIQE%W zH#8Fd!*odMcfV^q_7SBvk_Z05#Q+a?4jYr4juiZLe|M~$f2?3f_7_C}abQnR50Hvs zGx%rd>F8-k_z?_0R*)3=8}A=tI(}%WfLNO({V&+&&%1Z5>hwuX0|36U!D!eJdLEdo zzEx|(1D`lKIYk&du15duj)asrLa8K7QGooz5{ap3Y5fJhw4Ql};ffsrErX6f0ULKF zHBEA9>g4TSf}v_YY&s>GPe3U6Y4!Z@z^qq{;K4hXFl?t9v$@&g!@+Zc>^$EKp7We; zd<35O_({b%v=C~mOil&}88(w1oSG^fe%}|c8+CGu@a8_0G_$R0mmfYcCelC9TN_#X z{st+e%j=Uq-Kv>$M+X%^6d4(##n5(NzFjMGZvV$;k7Ktgrc0&H!*JiSKzi2O@cmRr+*d#M~C*(BblCQ#o7(r zw)lKoAI>zZ?Q+^z?Gz?Nr7;ZA^}6f60pVu`HQxGB?`xTj#mHJb4p{PwVra0pG5+&C zHsw?6WR2)=Q`p0M==`U8rqYMh<)!6cv+(CHCn%G`dwRBqO&`=IEGgg4kjw0|05Tk-p1|0plkcvS_4j?->}F zjAjm}qnE;S|5C5RWU)+|HLg9nZK-OvODh5*E^$97 zhKVC?QuA93pOvj#Aa4I;^o8Bc+OJs(SU~y3zqz?Qh;xl+g#p#hYgxT-+ewKpc| z=4HM=hHQVHk^xQPjy}X;#l#%m(kS04Zy)GUSYSUMK7b;Tf+GT%*a!H>*b;lCA?xKh zwOkd4wPr@QA75~JwFF)SpM$MS0A&>Z!HOr~>eO;$7!5_l@c7>GXTWyU!50aKs4Y}_ zxx$pLI*Ig6EG*r)>R@RF1w63XK&}8HDbQKmqeq^DX+8(<2TAZ9WF?bgnVJ%|4-63H z+UYU<_XT^Q_}uN*ZYG@6bMB6vWoS6Uiokc6Gu`#o#6#UUb%{U3H? z`{wqda`JMU4`q%91b)TeKi>E@Vz3f-)t@g}m8l_~Ee?E~-I*s1ncWuz!nBLwa5Sq0 zNdDfpSaz|{c)UrM2I#L6mjR~St}m`$w4ss}7OwdgB+uxw^YLkcj$>Dkgb!*QUbpfC zD@ZJy8Wg^`V=f|!DJ?Hgq+N#*7{yFc6HLaewYdqX5#~21dDhS zQ<~yMaTUAeqZ88JGcw{yb&6z9yOko>*Es0(}T!R8e^MJ$SYSzrS z4v>4Cbam?^IjkNv#c^dI$&z|UTtx}ko!-cJtPv>(l)cXMfT zmVlxVXwJ1-V!av7hQ3i!QBmJh2jBnkwQ^v0)t4T^rHjcr`<=^6JC9iijU5{nyGb+0eG2Jm9+BM9n8U*# zvqOvk_(qCG8EH*?%LE$CND+!^Z)VpO~Mr>zh>^0wk2Dwm(c1!OZjH z`-=+}E1zC`+z(gLTG&Q0KKt?-m&ew`Z+4H>aiI^FQA+^GwCmE2z`|!}W)@Jlvtux` z*WK54eZ$5k-)*!iyCE`uB~vul%eR%6K2Z3akMVv9Evn6|hR#$bJ zVma=znUC~NmU)nhqmW!?zBqi#KQD@$B0>h1<6})1%Tmt9yW&yp4-L`4)VR^;iHn+A zS8q3vkaU!m5dMyF1)mw+PWYfG9BBH><0H}Tp zN{IsC9B%1zO3ial6HHtmu#DByt`e90Vi_BWTEdykeKcMV^X50yFw|Q zvydU@r1`zzW1oi$%@dbdQ7<0snL-@p-a?siQf~e`z+$=I%}lBwQMdjqXz`=4#apKX zvG?M07Eloo4SdLLWDN_`l~z(xhvp!~4souI>mS}{aqajS&&A+rgESJ1c6HfbE&?6d z(S=*1dK7P^1TcrUEHY9WPoXy3Gf8`C4YiSp~GXuGU7?#rt{yhPv2P`*H`Euqt24k`m`5>+H?`f@!Wm@Yc{El3dBN;b+`qGH~5u*7r)}Y06T~m1Ak#K?Zb3gH0EJg^mMv zg2S^%OUP`O-R}R>LmcqRbAC*7|Azs4hulIWP?0^TFnS8a0US(ZKp^1fwK`r$KjmCb z!BuC??rVqn=(!EQqg&3)qz?4)f%spT`xhFpV(rPE$ajz7@fOYRJa!fzy;*wLa`t*@|L8a z;1=-~*Yl4OXYw6C(LJA2T>L!>$XWBYN5%q=mjD+5>AG_2(~l($zEhBD<2l`T{_5@! z^hU_o&TtE0J^=@Z-aMCU1iW&PQTSwZF{h@c#L+oWe<+9&Ks2Azc^CtWoZLMi9cy0m z5kEb9Gx3s?C%x<|*wu;w780oRWuVriRKY)LBcsFf`ln4h9t*hO-!^kXK8vKrT^j1( zBaejI-r@OC?Pj%V*Hes{_{&LdU%?6P6tP8d^PnCRNXg0Nz14s(K6>w{WrmMGLji?_ zt~T>x8>?pyz-oK63(mup2jZzRfUiGxPJkXc1x4_2U1gDQQEfy+209C%VTwGr!E&kx z$J#N#y*ix=-tMk6aUymO)zHd#1jkoEjb0Qw#Sjc1&orw*ia*CsPX+Y@F8*g{D&^xF zN55x&Q;%g4Ne^cYo~|bJb^NJy8`nCQeYZdh{@a@{wD$tQ8|Htw)^Sb;`ukV^ZGW-< zOB(&n3C$Cc>wPLbVl^5^U_)WZXV))73|btkO0U3vyGQyEuk8fxDJ&m7$sh6m`(T|W z|2bPa80`O@d;i}ADA{9)7ff??akY@%UygGlbWjvCRZ!^nGl6mMq#O5#`s-fpwE@2^ z3k*Z*m!ayn`@fmKf4lpCqXzkp`qOls)5AWYGM-;2lqxG(TFD}f2i#%kobUWLP|Z)L zl@u^ItE=Y+-h=uGp@YZ(0?fSfZC1fEO&;_L#;yN_R^Y#@nE&Il{y*L5FMBx**002( z?drS`w!GLKUlOpn{RzQ$`zkVehZ0LltdOF`tF`h6u~Tt6uoWF{SGFP#JYKnk0-ma@ z#AxFc>hK`LE>Anbq^@WdwSQPeJ-?r4Kc1Dm^jxiH_i#<4`UbkBa^!~VYF^*;tyisf zc?ary+iq^b8wWIWrQ9QjEh8?(N4`#!xxZ1BHYdQMqIS^Ld*)pb+?MGwOM2OvAP@Gv|fI*HnmX{t| zA|ayFuPklnY3XJ>H`yHiSL)2Mi|M=%ra9bHZA4=YOj{n4c*x7uHnx;j^zNEDOtctq zk95tupr^O`23F6xRE|85A~514Sl&<z4E5ZK+~WcWlvhsDCSwP8wG)z!?%?%}KbJ zu{i@=7XUX~RD^h9Wh}~qD6RpRtybHyuNO1C@s?iZ7N5h-ZbM8 zNtOEh4E4^0A=FlP*v;#sF7oKXsk@b=I*6K0Y1{4hgjnL(Z+hZgL&ksI)iNKh>a%z* zX`RA(CEEDMx&udqU-n?JA*iS`nJlI|nY;yx$c9A3SvmL-uq7!v4R8*OM>`#K!M(r9 z18*z=0fEpb0s^{n>qc&HYAny_IW0-hV2PWe$uNSHji&^%1gymuS96$-tiC7WrH&3D zrkb&!=bhYpNtB0hb?7B_RBK|f8A|zRQ2P^wlt-*fQ^RmS{zJfxo9EhS>`R#ZeFPPb zsBO%1R?63A_*Pt0R1=TfoMO>718$Lnh$;Jpf!NIuw_4tGXq|SVd2Jj+BO<1$j-2tN zD1VU%!^I8**XRzS5$N(GIt*nsT{O+t9SwL|sQq}T z&_bTTB%9`u%#2eAQo?UKZf`+-x!kmQxZS=Y@ElOH&FJs zd+T^q##(H)koz$Ta8V~?i^rQmz#L2W)K+3|XKDV5Z4)r+YWFX^xyYr?W=qgVc+J#> zMWKssw!11K*2QqBYIB5r#4;%`_}r&YMTYZfT5w7qhvGFK!WVZn2Lnt2ds{f7!R-1- zE)XwlugNv1@Cu&p&`rKd#p=>*MM`Dxi$~H$o%AkV&`KwA=lD zq8irJaaD*0Z}fr!^h1R|J`3p=R9{Emi2>WJ1ZL$_Oc5uHBvu^mfP2s6HH7HqTlai< z%4z(pVm3*!HnaH}(k9C+z;xFRi%WS#?ZaN|_99O&&ce@wq>xr$0pX-O$c9?*#F7nT zC*(Hxa~7wr)x0__Q08b>jZCYZjgAZj_nA0q(ziqte8p3BGz>rMJcKa92f_oNB4B zTG5%`1lyvovBH_Jr{#yo0dVuW{}IA!IT8+VqffU2#_--hj|kt*tu|&nL4D%@m(R!~ zf1Fm@LkL>jADtP{KfV2+xihr=Wz_keM24F30_EGVDAvxg zB8Nt&O7pFEmHD>Qb-Y3~{B}!8%wrlO>-kR^^?_H-L@fkab039WTw@<$@lQ6!%`f?; zjl-QPm%jjznER2u1H2nCxG!BJ^s7s&(?U{ybSU-_o^i^Mqb^wOXkgPxM=>2q)(8Z>N^4UUoX-J22)bm#>T4ITaJd4Hz#mX=!wUU zq$9r}Hs#<$dn<&MBZ|@rMD)%*wJyMk6)j#|g$;-6k#ti6S6<%@-1D}J{lFw*sx08VMyoe87wP!>G`69!+)k+5(n<>L`fK!a<74SnmV?Q5 zaL$mWjjHMUJX~Pn^REP83?EDeI9Yt7rn;&1l9o+JqO}=278ZPiWHRJTMoUT4$6IAT zb}Zil1mpQYfvK^??ljeNh=u+wDgyRcBI(`@^Qvumiw-%QS_TI0!>(z);^ivwYl6m3 z#_^pDPvbbvl_1u|_lEpeUqUit;LL2XG{y{)q`!YgI==psVyk|k%J%*2bCbT|UEdIz zMw+pgy3^|qNnp57*-ZQ87XH5Yz+o%}mqSYjpzyy;hT~O!)DIE(1lcZ)U;$Os(Spi# ziM_9Ph7Y(oFqIc4k3zxseb;a5c91eCnXN z8sbWdRztM({i~OJ3Ez!Ia_K7UeH9(OjdfwW6a|2AKBN@qJ|6`*=`Kv=*UjA4N3u87 zipKVYLboGt!yXS#<-~yZzE5?x(AfUv;nmE69pBXWZbhfDWF#VDYQAqh?&$ac1#Q0e zbU>_LlkDd4Mu$r_L8Am0u$zPPoyWZ_SQ~Io&2ePaDmf_|up9rd_0;YRKVCk+I+DpZ zfIC{T=~)}lp4TN2kF{LAnj;-eNoyOLEtbGQhAq)*9>fo}qgBP#OkE#)pfZNYC%gol zb9~_470Y-yv3Kdb`?)cx;dcfGCiiXqUdHe#GGe~ThZv_)j$832Bhf01vUJF_qdi~g zFLlx{vMbWBtag;M5yR!X8|V!U^j`_>0mE_XCk^s275na!!qicv6C!}k^`xi3Wr#Zj;Lkwd)iPnD_pZ1EQCEpi++?(jF5zSr z-wFHlDc`WM?LJqWVpinqD#YRU7wnD;20gnp4K!LiU4}}_qh&n3=M#RB?~)1C^+|^# zWeZxtFOg{QPlgTHP9Y$yx%NG^s7icSg$2r$Tj@<|(Kff6c<>b_X^}g_G2_J=u8Jd5 zx>?*x*a?n{o?3e1u5`hB2mXA4w7a$wx(X#dC;V5!W>tp(Nkhn_w7LROvS*+VBWdOl zX)n}MhPFwzPGX_cq*cvUA{&s0rIzthIm+}FHSnk+d>oZtMgQ$dm2bSy|0~Sqm&K&*O<3Rv=4jc{oLO%e`AxrDIK#0X2#xACE*5~uJ>$-hA^`bIs0q-<8Xg}*=ai8wTSpIM0G^< zX1K2gp~~i>*JE+dT^&~q;qdUfi;b<`8pAfGErn?TF$BJPO|6eJ$5hIVWmynxaCt%b zysh~184MsGUujq^( zxL7P~=VxyzDk#(yWw@;I`Yk{_@biY^1>>dI0dBG*wVKbbOk(>A)Nui%6alqCm`JVV zANv-)JG z0rRUkco|Wv=(e9z(L(zgJv;%kx^g-&NF?1V+6qNAJxwKzvH{6Qe=N?AH(g9$cU)FN zm-I~-+MEYgcNbtE^oVcf2=^2aXv$mExJUwAjOXS6n_lUpwXE$l{;i#~eQ1aPFiOB; zM>IL9E3K|hMCuXfg&MCzZd;6N_4p|<+BWrR!PA8-T?hdF5}@eSZjEB40GSeX(Ca4(A z7C!RU%Qab16VKt}K?Bilt>S6#>%#?>8)!VHrT~YDJprDv82D`W>jDXJ#*zNMw>$Of zYNDf)^jgy8fM789Pwm00OIn97_S@U~t^;?L_KpF(91xvR&#msGAP-1NSQw-0&~_xJ zgNRrhH|rC>Z{|U6HRIFUJ%odn(b5aYvgNlkS9##*7yzht(axs5{oug%H<}T`kh+QK zv1Br497??;4UV-G*`)hQ;oT#jZRzOaitnhS7I3C?dw!5!MQs>Y0Zv!at?*fE`1Vli z0d0%Ay>i752l~Ju`Jd%?P+g^sTC>@2^7W8A70vfwLo9^hnnZxp1K!9Dzs%JJcK!BQ z2Qhi)tP<{EdB)Dj8{PRjQ!mfi5yAM~iggEjV)dJ7E&Cr+hxuHMc~Cb8S3o`v%nq=@ z?}dwsisnuG5i+x3(>}#b&ts>Jw;8xC&HQX7)Neu*JdfO5_8oSzL%u63Gcb4`=uzkK z-rT@zr*4PccEP@=7$K;lqEduFz*U@7fGu3$eJxJGQogG+k7! z8i{mM5&z5quj^~-ZOT5JvzWXX#2PYio_)Df8OWWQc!zOORabXcE2*kdUhGd3H4=tJ zUIjfs@du+B7Nv+jRB=5}aG{z^JosUN&i1#}pr_m^jX;hKct003mCyAdPZgGFC=6)q zY^N%D2TSB_i0+)&sSNIKuk>kevT4RTdd*fUXlZFxrCaJ2Yn>ZFo`QZyKKLCR3?sLt zRHrbM4XjI45+3BMsvPA4ldNRKOWs=`($sm)U9hkBj%{U&N0WAS&xMPwQa`>f(D2`W z1k#%UaJT^>PX-3Vg9eeeGBEsBRMdGZ%d^z3xM=8T{OLz^;WW^dK!x6yttofM8n3u3 z@f{y#|KE_NA1!8I@3Sa;UP$OB01B7G7qDN){_wa(`$KEL9wkh8J=zA6pmVQ__LgWt z1k`6oBy##e^6tl2fu|9=q0SdFFx}?;LV89i-x27563}xPCZsQ0RQ|Aw0LaX{cG|0tvKVX|HQ{vhr#lh&;3eZWH#1z%DPQe zg6UH9t~F|xy>Cx1A-C;~-ev=PpnHn+tsi(pmh$v%RKqj6qG7XZS|IXSWL{ z(7)jZ7;zVMFEGoR;G6aVILXj5-_`xaFxv-Fv@QYc%$0u8XxzuoMnC&Wn0hBJat~20cg()pCG4SO!jgWcIlvwgLG)>7{n2kN zea)*c37xw?Hg74Hz&$m_&JegORL!tEEh_=OF^qvtu4mP=#WqVONy4{9Z_Ib<)ZvrjGRu|rcJ>tV;mzm}i3S*N zZJIB(Lg7I9sd8?R`FN@#0`nqvp8=F>S1l-cF|(>A3(raU?S$LS&?XPjbEh%aj zTC){(_F7n=0;cWIllvS_A-YUfN3*F4(v<8I0$mI44ijtCv%@cE?W?Z270Xvd92{Bd zN*5E||LN?3<6;^0i@fwOpMM!WxZy)S&u4IH9U!eKPAFZLgn%4jpW;r*bk7o_g)D_Q z&rJ9o)Wu%nZlxnTxdM8>uAd(w4~eUjgAve52hkU-yE2gcuD8Xds|hX(PC@Zpm%l2D zlvYoUyS5TR+p*hVX4VdmSK64bS%+xTtv4XXzis=#~7I6;5I41H()LT9fAfDhK9tts~}98bEW zTs+Hi#j4yDiSn$5xlQ4I!-dX|NJM8fqhROZYcVR+TnWyT;}T;G3PXFdO@+5~crH>m zggGC|akyBledhZc30gBza@$VTSn8{e{@zsl`y1*1>$7+T2w*W!v`=4esb6l_yz9yN z$9wCyZE3UbwCkh0_M?UM)+idN53-oFTF^(yqAL)4dP|?>HI`j%^Xo_FHY&h{M-;Pa zuS>-ib@!Hffdak9iKdALtbnD{)2l^n4l~V)>?V0#bb^WBZwh`)70JOXzP15AP>;vm_)hFmZkDP#Opyy z$8JRvx-#bW>MOSfrlWV4@E_Zr%8f5YHC9(^Z|=vgQ5_|M(N6c$oY+z09ZPz=G|+}B zrW>dV&f;K)blbP0oD^kl?bHv+77$*1FZ2(~_Wo3rH)*%w>zF9DNtAzn8oeR2+Ii}g zS@W8BZ*Qhol=e?^_k<#CbX>4jA);|=UC+91VNCA_flwNiLI}C-VT1^T|_L zY3UPv1P);ofxN%g(y#5p>&9dx#bzC5b`-R>HeatQZc!d^;^F$3gq6;Wt;zrl!MrdYetO%|}}Pc@wXf^ZTd$VPDhK zrHKb6ao*E$8}vG6+hy!-FTp^|kuyFFY5@8NJdX&ac|g6;PKs-tk2L{?YkCbJ&ID=f zZ-@8uGChpq@Xs4Hbq+;g)_HG1MAKvE50VPoSZNwI)*PDbLuAefjz<*Nd3v49z|-)) zPCM|SDJ#wvS*Tx{B7|h!=PU{k6+Y5;_3G5gdmo5+8s}SaPI9R3rHqO+02%xmcu&Si z^8b+1)WRa{IuCZ+axxG?Z(*BbBvJZjf53e=;4ev za4mnzBd5jtiAhV~5K;1qYRxUplSauWno-2}%@a~_*{5ht9Fx~~=Xs1SyXk34331N~ zB*f(Khd++@<7Y&K30s+|H?aN#)utI}e+Lweu=VO%h`LUV@}k+s?29I0KE=IA^<{)Yq0V*|6z6e5vX zrV+IKh2RVM+8G1EfewN6s}Ky6EXb9P6N8Jh1=a^K12a?WQAWYvE0w{pm1BN6d-?>i z%c8)SLQjK*De7@wn|0Z`XWFi7V5%{me5`~uxq@__1-ehO8c=(#&9ET~n7_?J_>V`a<%D{kbaFx>pV5u%Go7ct>tPp8-3~9Gkm? z3%UnFL&vV8Hf64DFP1e!#9k7&ZI)UR;M}TAOq^dL5Ou-8isU|^T$20o-h(djf0xLV zL_icMlm?v^!Kw!fKU(vr#m9y=3D!f!tw{7g@P zgbiK040)3-RC3nrnge*eRpTL19wTHx*g9%?-V{$b@Cl(%ra+&w4r9RXrAdmzT-p}m z?5PrP?oh-25_}VV`xGa?3`m_Eay0}%%(Aiz^>Hiez?&M%sU|F=^Nr1xLG?JuT@!XD zm1lLv#j9sPt*L+dY|OOEwV`$_F&XvVq`JF>BepcceHB?yMx{YIO}$&Ix}>vH_R-KN z@6px6--8laQeeHMZaNeln7#QHcgn#k+N;lsskXQiug93ni@4EuG2Tbw8> z*<4l8uc>FYy{Kaf4on4~H_F--Xv<)D{t1=W{QXtjZt=%uKoZcunuXQOB`e?7|9moj z$q{-ahs6KUWUqe&-gXclGnyQ7|B8I(^ZA`1CT(PjoSdThDtfBBx{BP){zT>+l>Gzk zu>Ueu@4-DMH%D-p8N{K0O5^&+g1+UnzAR;J7^*7iULhqpoVLEx1|ZFNZh*U@#??C~ z)@Bbj9u{4ryeY%)Y9W+1%0uMWT5A*B7GVE#KzH|BF23VK)2+cE;vWUi9ss5*3Y43R zed%J6`aJj{-n1u9c#gG*o4@a4@jsAQQ3S(kO&#hEVfEYBpV9sW?||B%Q7XCYEoIN% z-HXS}9#_MbANhF1wX&;lGzSZd)3vr|4)3U=$syLE+bR-xz;HMlU?3GOxV119tThyU zS?ei!kiAlKaMcK;D=1tVAP@+rCG1l8TrACr+uAbF7w+dm>Y7k;0n&$O`O!uQiG z0klu*6x=aogf1!R}Hmky+fW2*lWC7cfMR_?V#U2CjqQ>f7}i|VH%s2 zV*C8|wXCSaH{h8mwu~r;zB7V;jCQpCwJcD+As(l60t#Zbyg8_IuXO-50=^)1Xl$)u zHoOYvmagk@=lj+N@nLmH>!1l2;<{1ULnBq;r{7!BUST$|1pr(1kbLrHvF+WETQ{^RQ46Go5yma;VS z?}T-UAMNWF1J@mnfrzp3GJyV~f`=k1oGQ+O$UHJ~(V`Facxf|>9yy4+1{#$8dwzX1 zJ{Nk+Yk*EaB}k8+<0$iJ^~AngIc=}|`O}Mwi$Pw`@BX6dJ{(iZ+|;X4#~U7X zA5KjVBDvy(BI9RpZ8kvt3f)nkivsv#>y_8H$r`jLsJb%w<*Aa zwf@6k ze2*H?g`3*@J?;bCX|X|U6j1O$)l~^Ga!h(TV57gqHCDM1&to`Qbx z3E?&Mawy_wr7#pFA#rD-6>SEQcx#}^?ONda%xgs4=25ezDp&ScW}IV2du6mYAjRos z1olJnu|FSonMI74YAPfv+MR~7cO>YW1B0a!lag+ujEo?(0#0_6!FXA0i1n;+$nGYl z%NA7~gq2&=90l|(f%A7ERUd_I6HszyMQG60QPh}`frzQeTBX44)Vop%LqU16P+=$@ zwEV1L^W|FZ8zuO{7JRSM?0d~u%ACW{9O-2=u9;Jn&g6_{ZKd;MlugTT=EhmdYEm&0 z5=lu(uVoB7=v0ym{{y$uducalen`!a_9OGQ3xcXL&{JUSy$0M3*q1cX?T);3aGyoT zNB0(fowjus9JgZx`r*=dlq4n3Wz}5Q;|`g1HB?foricOTF`N1aj;10~Kp<8z)4qHT z=5P@qZ5DZiD&6s}_<^~(xgcQB?WXOh%atxr340L~z=4}nBHDo)F%TO&`?X12%w=&~ z1hm2>Bfj6U@-g|prfB=4>B|+5@8I#mgaAV)w~eA{;T7Xu;hCTH`qDLY*IMyndap=V zUI39+@H=e-w8)k|HUZ9)36uzyhgBcS1q#Z<+!L9Cn5@*1%%RJ7ZhPdYT7a4KErhaw z<{O=WpHcGW%!|`RRC2UT2}H@w$#<)=%-FXV#6c#l9oO^;TCQ`Vt-!>!Ti_+m1ra1d z1;{7I<&UOE`2wtft1#|OkXS-j3GivxXC}T`0bObIEji@5-W2(e zF4|fAc|Dyw$0fw8-3Ou|&XBw_hVB>xorg>u=N4xrSv0q?aSt};&S2X2p;nQ6Y6(VG zPY&b>YvQ^k^n)${j|Q%XE7TQ>KLXg_Zle^ECz6*AiY1~bagXbZ(%alX&j|up1EF^( z+H5@z$zfRYuNMB0D=i0DWFuJHmGYMD7fLSsD#9t&*475#TDweDT3*Ba-@^Lf_#T$P zUN3Ll6!2q)q2X7}Znz@t>lSu(lAwr%a8wDpyNjY zT`So?|zZA6!0V8`Wa{35>wgtx7 zrwQDNLg(GSN$|G=rHY1`o+E*lb!s@AZEi|3EgbQi&XS|{^g4Ym2?GJUjWvpkq)MC4 zKjlbgq82sj+4cM|{kTH65X=rO^+9D(|{=J5((R^(KhIfjkmFqAY+9oi2xWF z9X>{w#2}#QgkyC+joiA1je#Vb`IMFR&&TM{UO9j9|4j79bra7z)gz?CH&PnB^_Eg07+&?%&e3KqCd_h6R|9Tx5I@xqEPPhwdBn z$hCsGExn_8M#bdg*S({^^S*+j0>{}lpso`58mpqK(PAE-rZdBx3ow{#FEC#GHWnF= zeZ|OxunvyBRI%HTxN-zEMv>XOXh^DTLe9j7fX4GBkxpfBzE~+{xJ%frS&8qFO;6S} zxT>DlZ(pT2g86&Mh2%d)@QfU20cKMzh`aoct4AgHY0O}bM!|%*Bl8i5R)Kq+Vhd}T zk76y3^W>HoGLn$UMlTp|Rl>6RX`PG#;!nU&q7<@N>NF_Zr5Uh3QOW93=j#?y@8~!^ zVGxkKJ9wkC?DZ2B*f6M0S~@ra;@4y34WRjAA3Ig&}ed|h@ zCd7(KAFbnkZIy`Pvp)<{pX0#z0+ls7sq<%r4#@lS+mrtrwsif8uK6d`kgn38p?nw! z>B$cR-u$SO0L&1@*NUAVjz*;F`UUr8C`%96J$Vcappq3NO|rkFIJr%+LgkXE(4E-c zVBcFO56Zm=T%B>HQ>tNrs^p#sr@*mj%ZI-h{$@76rc)#%Hwd;wZB2cb81RJws5n;w z(UN@RBn9=W{RS*+5=W zVNU8G@k@?P{UtW-S|P#5RL$}M1jiGj#~yNOr)vqxvfP9wQH^%Q+ilz9A!6J;CTfImP+ zfoe(Oi!}%8 z1I0CwnLGZLYg?W#o^N|*NoR6wqf_4P8o4rh0k7^vKwYxb@0gzBpu;SBwjWCOYs;2| zz0fO!_*3FuyPBq$3P`%raE=*Z>QXZoOKk%Ejk8rXcQ@uzc4Ayec%YPuM;9Rqb{}!; ziTtcb9^GYsm9@0!@b(Y{JP^j`RSV@nG`Bswzdli`GBrJ2t>^Q` zBdgP(1p)q8hn%=W2Bu9(+tsBXemH&yzQ%w#V=i3 z(R?stYkqm?e_cJ|$t0aDhhtHTC*C<1)a}-RU{3_fH&lr^(J3iQ;%^1cP&1nVOE*x| zAT3FGk>VtHYzg+!qf01x;myo)B^ST*Xm)I4no=++^A>Pm&FKr zFw~>%ix&u;zonU^d=;Ea#v1uNf%6T%Pz#u~oYu==4jGO&l>!-5Fvd`rJiz_$G~u6U zXH=D50fT6kIlALT*BPWG#?_QbmkbX{A?gcZIio@%4wPe}?YZii({9G}&v*QnZl8}AWQ{e!q zum5W_9`xwi&6;)rgdr+jDQtDSVXI1bQI*=gxL^YjKwtiHF36s$L>ZW}4Xp74!8Ab9 z=$?EG0)xIJ+vuk{uj%v=`qJ3gVh!<=Pt(q#h67<5#oR6$q0Zu%<$QcAJ1&kP&o~rX zVwCJ<q{wFJ6zV+7872Qj-S0fW9 z{Are*Ri!+xpey`tWj>~`yR97M??2GTo*5h*)~3bua1smjS5h`m#g#>}K5g7&{g9I) zI#st-;wZ3-~m-2x_DZix-yATz`XeOUSHtZXHN0MvVW2(@cLonKaVwU{B zjg}$|hnpjbkqOklQHl|b)rb+Xip~8FWy;bpSZl?}?$Iovcd!jXX`BR6Aojr5TA_91TY^;bnH@s#} ziQe#zh|N$3s2QQErgjH`LP7QycLVpQPXqPQXml4N=AxeDLT#_Ll>D80-_B3eU=Zt% zCzH1JZ=QYbJd^4tTQOLdot@3vAYchW1L1Sb4>EGSbH9vv5fJ0EL18uZ(rm5Oeqo~0 zA?p*Ss#J*+ChclZ(QBJw;?)7{x(4p1_UR3khu>ZW(X`1~kM0zVO3OcKUTX_+Ztpq~ z=@uiQu26eruehrv*{kE}p-J0Q=E+~04!(b%`rOXt`Hx?fb9?OTi?`owQ5cG; zbm{6+Iu-|3WAEBwOR4P2LT|GR@$=yu+I6Joc)c?Mx?4|l_O^#7ssfD4FLM(BeU#U7 z!{g@U_P;xgdrxmVs=KcKzK>m`kc3IaY9*)pHQYW7DftElA5B)dI=%E65MZw!5yA7J zxE2z!9(6G+tqQ(gXmXz$|Fq`YbV*BFTWEvva=b+kI9pElf6N1Ks>2m&Xp|PG<$Tj& zmqv&wRt*JE|J}Rm05uC{)O(rgl;l=l7Dw*u>$Gi0@|(SX1%tGe!tV5G1_ky3{%~<1 zU1(upA(HvMo674Sd+9p*rBy2nc^F$X{cPR*lfK^GkO?uWaO^71MLy5S!*BJVw3uTz z`Fx5Y^<``%I*U;tBQImDQv$L;+dheQ$CJ%t6s&ob6cwBHX4b`VuDOBPG2Zl6`j*Q; zTs$RSuVTd)QiK$a(KeZ2{>};~4Q^bGiK8K$opRX21K(YwB}T=7wX+ zZ#0L7oq=hg!Jt_=WX8)YX-WO4$9qu=kw)k^_+mp%%19pd!c+=vXfFNTLxx@VFqX*at8zv`)MrT_Gsk|C5 z+nJyZLNzob`(t7=FVMRD^3P)di(fOQv*jKY7neqjw{UVac*|6OvB)3qfvME7`B5eHl!-Y-*y6 zAX&y|uEAe$EqXU+&K_(@T{@cXLtKgjzCw%8FT+gIr%Si|#pGb#Gc`(qwd?nE+^0T2 z>@-HtrnLOF1;`~M9qQh&pHE@)@)i4Zv>J)V-y*Tvk-XGo)RmF0SP|j;{Gue(jT>s6 z$=>z|a`W4_GElX!weNbQcc?%*l;etUcXy|d*m*}1oHy4sJ?Xa|f8aSPcnnz=gPBIu%Mz?7nf`xw+s>kS z4;U&|ecPd8Sz?t>x^rwA9-4=;!{;Jx4~t!N&kA(Q#P)b#a86LxfAZVNwI5#nQKntD zr1isrSC^Z$wVcr>`PZPaP3ykk9Y;Z!z4CGYYQwym@RHWa!@tjZm(gcMvF8L}_KDyb z{UCOvCuxf=(0fMzW(%{WzH2%CwMQD0#P*3WSWC%s9ed{WcSL2R`%^TU6t|e=aW?_0 zt{donCpvA@asStKAJ2a9WaMN`12>kJSMMTDpZ4&Ke#GT3EeyQmgoggWuDA5G0zi>b z*|6SDhyX;xqLwMywoVc=)c$VjfjJ_p^daN*3;Y#3IDoO?yU2=qtfEf<+_dt84)51 z77M_E)Y)aJ=67d;Tp^&l|0IW7e657?4igR%y7REPPkn{wGFRX#Oh)hPgwW~1k2MQN zDujy8tNGs#-K-j1oWFqL43Tb|1O%*mJ^Hv$Hq&cW%?=Ir2<1z|W2~LNMKvt{ZGGF) z)pZO7J%;yfXBPjtupxNZwK`s zSt4CRxEH#PwfCOul-O+6Q>Z@q&~hP3$$9x*2P$y$aZLH}Mdwe$6))1k0B^Djjms*z6tJ#l^*I zwoYwfr?azD2{ghaj=N9ikc6eP{pLA+XUPRdHwKGoeA|-SQes9Z>K{OOREE2U_1*)T{Nul+HF?x?GLA zx>9>f2_e3`{4wB%-*Ht~>b`@)N23*);8d%W(weW4h1tfL4}$+b4s)HZ^Nw_n5mA#m zVW?aIRdM6QR&8;|ZJYAkyobTF+lk|f$k*$BujZBB$$up$NSj8*$8+|ZLVV+sm(QF% zdsXpy?@O<2gc%Gc^*uMH6yaCKHar?$#$i`H9|2-nKJ2ka&fZAD*li#H5(t9 z3p?!DSupy2wInz^T!*fiPU@P*J2S(hrcu#RxqtojQ>=%D`UBQP!?vrhac^m|ZZlO5 zx9_yR^2n&S<;U3v0jOc+LM*korms7Zove4J+0K4gPaW~Xtnq$Ms>heLmF|Ea4($In z8RZ)3Zk%D4@`$@y>v`J!u0>C^x*=SzR;?Bo{j&>H(-1`e+o7x~d`w6C4?o3aX;Z#qbT#z_t$RIp zPD%*g3O{b>;SCJ-rH;fK3$4eF9zC6upkQX>pz{&NA>_sLC!r*`Eo zuSiWz%{jT%Dq782xwT$i*&*{7F{ndeL3Tbk|WDBd@ z)}N{RwyD96K;*ppNjG1u9@d5?%I}wy8*jw!2nzN$qi+M$abe^Y=;C$nP1|i}2%S%j zb9`c4etAA?K`vfc_jvh*i@64|rm8L@izbmMfZ3$LQ|Mhyxtb05(sk7<-I<%4o2(g2 zf|=1xYef^YUr*LKk47z1<2?Kpe9@M~tVcshUSzE*YxqSkdSnf3Q5G6sfSWSFPsZp}st zNp+!#yBn-AX4_eHav;i7nFF}AtwO&k!@@h>CMM;%(8@pg{hxyP!2EqMfWTq*gW3H0 ziNo_<&=zb9X&>|#`*G`@Cp-JmWVQCfR%ZH#(MrFiWYxme=J71nR;u>imzuudZ!09q zAdaY{P#qzocrET&oR*40wUw8HP^^N9M_Q6$hG<<^e3B9MRZ;g`-rVHq*?NU0=@Ug; zW+s*aJ)ZSyC)S;xaqrx`sc&hiZ)BuzZCyTc;BZ6xqS!fK?5rqC>@qDcclnLaV@HaJ zLbLtpG8jw_pOcf*p_xs4O%gZJaUo|mdfbiI#5FH;*=(~YHGS8>%q&d+y4nRa<)vZ> zr>I>q(dnzJGIDa$OH0c}$kuB<_kOKYDpTC?&v88>ad_mk&Y|7)$%MD1Z$XG#Eig90 zgw=UZgQ<8iTUA@&36_FNKtZ9q{EeVsl88)w$iuIfBi;KlbbTwBz9#LOmOxVtx>KNl zG$)L3C4#rVvQ}WYbH14N3{>));wojm-4FOK3``q_-LB?GlFq^UY?G5`o2lbCmI-H# z=#XCheWu(gFo5vOL8%xKVO-lHVea4Wnrqdvof>tld~HN$b#={kgYKRYZvOL!_q_RW z^vrpM5IZJjCU3~aW&h9awD0rMJwAW_3=F$iM7c}L`!B^G{PqnCyCw^>&I0PHG497# z!gXpJcNYU!fiXzBbR%HI|m$NJ?2XXu$oH)Zb_06IPXhuvfkgTG(H)Zj zlRhmO-Gh~BpT@?{!8w!o(}P9gc48ISy%Gv1B}>9mHn~}+I@C7j_z3X80z9shrl+>k zYF%n4I6FHlTOk3G!SM@;V2&jsuzu52Cs#Un_&*1!c5^b}5iug7=jIB`t!Zx;+C++q zak+6e@5Wt*{Y+2%j=1KhG~$WeOK0^<;6!zGi})^lraCdgR>i&Zk39pap7_t}Y1Nd~ zL7ZlCg^f6__3Kmv5IA!%)~GSm41*a0jUNL&5h%Oc2eJ!GYvc<|g1;i`($rPYWy>|U3u?{}GjY2Zzt5b5=1_#!IDm2W zr0%Aw`iFwflj4^JnkI9`7c}+Aeq*A;%AVGqMxhI4bJ2Bibv1p|$-zN6ysor2Lp<2+ z!IYcp)Zb^#I+9;{D^&#tP*7r~gVqp|5bR+#d zxLuHh$Ax`zB=fxDRFvlqIOyN>LA=+9`1cbx_SF0P_`esn} zX<*G;=jpg?jGdr=ZsN$i|M=(Bha#kU-3?H2Xq=LLxJpQ#Rj33O*A5h*(e7JVq(9b)vsjxO?4L*TrymAKvQ=j$IQ~N%eH+>lgrJ~v0b6G<8@E#>gvi?R1}rR z3AS6v>1?d7MkSS46||uBJGTFgf0noKXk;xO&Z{Z{$(A1T@=sUiwB%@1agFNa_$as@ zcnAzc9`i2{_2Jo5L;!a=rH5ZxH@3QWRS^9Ue?6lBQ;}X(p;r3n>I&0FcMV#>Ud`|KT4O5y5oa-|PS|Nsy`c1evpA z*z;km)Ls;fU-|w_B0;rj;Y4iFvsFT9MGaMfk&Kwvy<2B@JYa(N3LP>5B>J9q`kMp6 zNeaGKtL{xcgKOi#BHfOQDXW_5ea#CKw@!YkyqRyd#AJrVpKCD5uoD&>Ja;~9KR2Z_ zUn0o5W}Te1)l!(ED>k>!tEWDv@qW&6NV7mV3XvpG4i|BKeth)wuGln{o^RH18LxXm zKyT|eugTC9p1MDWc18Pxbn5L$HKg@RhJ=lsrfmQ&YHlu5 z+r&^l9M9_!IGewqAq3wc{QY=eV?DfV;xKnn0jpl(t`(zYk!UkuI8W^L^Qj}YkrH~OwBHB$vSR(P74*NGJrG?Ncg2HIGz>WR(=Y41XB?++A# zyZSo9=h$x=D8+I@{hYNE<6Te^=|c?ORh71XIeIcWAx>M#RBN+id1WQC6Az2ybNgWw zz-UONPtVLG7W@fT{=lpBza5}Q0KIl$xp!h>>WOr3zXez8j>=yQ2psoIh8?l>1JGE#MN;~{^obRtXy%S)^n^Za(DMLvi@XAnTh>t)4G`R zdXfq#2+NNsOAGn?ndUECNdMNv%zR;VuG5hTQS(sc`t++D`|0{O)l399Sbo$p^{d$l zvWC%M1zs{=?k@bWCzx#=nc>%kibRxxDu3&!jP%NElxsmL<%oi2$bqcaRG(3-| zA1N1>yHRH9a{9nlbE@% zJt&%KH4y4rJA9%T&<(cSEf%#F2Pn$#v_e7iw>J;lVupwQ|4J|5~vvZ9!vv7G)y9Bdhe^Db{C$i)PoO$P zkln-75<*n0_6>I#6Ktx6?VlRwW#z9kF$+#45z}Q-;51d1x!3O>ZBI%`x zD8h;8&8}m0ETr7_^z_VujFqt}X1bS$V!XiYk-Ih6>AJGWvHH5YE=wfezh^;xu&A`u z`2H?}sBC-FHr~H#0T8-}oRvlZV9qI4#=JHJTz2SYv78HYbJpYT&L9+;VCoz-EH`{E zuSQRJ>GS$?_p4JXl*wO;ZsTF5815!O0}0llT6MI$yJ3kBYHR7~)@@CLq;ZpSqnbHX zo!2aIA}o#%E3fU@+1pby=7>@dkwhFXx2pz?<`%Hy6=g-SKx-48aRSqb3B2XP9MEUJ zFex~g%n93DvzAV$XYx5yDZt6aHD7;hXf}jE9v9QOGPGamqKy3I`^>x$MCKZ_{lV+~ zd)3DsA2s;v49eTRV~I-t${UKeH0#tf$W9)fT5&1tniFr-?T^g1wE6WsjraxW%=#qU zHYtCW*upTQccd4ND0||duU+lDYHnq5VKnJhPT-S(m?E*W33uY~;0HiSSY+^9dj_@< zndr{tt{70ylG^02^&Z+;VTnpKUao$&^?utAVd2DP6&DVt{`+@_YXH?>KA9!4LN{^eC$g3B@-aQR4vV&rFGoXPcb5Z2YdbYOc5X`+BiG>s1i7TK}LRkZtk!X@j+N9 zWvka2XdkjP2|-Y=o|nMz!w+>ZbL^PwhBes9s0C==jj#e|B4rnhE&QCs7u=DvzS46_ zP|5qAaC@d{O9I*N{6?*ulGY+iKpcM#9!6psR_DUJ0S}^0P{9R?69% zadRAcJ=kX3t-r2y>hR{Nm41u@Rxe0WdoXQvCqHtpi_OM6eHEtbib@fV{}(8%q|8zi zyS@)q{sh?5|Lm0CvF0EDy`ttxiDB&-v?V39&V5^8J`5mMAom+fH<_6%AM% zv{*JF_{zA_a87lJiXP{AFQ5Z_??p8GAua(0fd7RLlosAp==a>Y%xX)P=hv8Ed0YGt#l;f{4=pDn-LL2u7{jdzjs*xf7+ASHn$s#mth zZWrjVChqJ^G%4(jKadtfJ7+%WqjT*L_wS#9P}^o3Kf8l%pwFSy6Qe*$O>L)fe~Y>J z+V1Q2n72LE7o=uf+a?U!=MfQai^@%l9zL=St3o|S9`u1}Q`du@4!J}Ua72EBL|31P ziVJzYQMPPuboeyr{Q}>y=-3bXEqK?kY|aafE0ykppnvsC@yz5UtE-bo# zK{KEW_-A2QW(g<{4HF-93mH+$XnQF^Bf!v8m>F~rP>pS0Qg?TEgTB2ErwHJn%0W-$Q;9!8!u>^MccZ18F{sDJ9?{xS}noHgPRHrr~8aWl|uFH z7CF0SL_Av}_$NS%%xHL#-zWutPKCy=I09Jaf^Y%5N*u3Xd!9LiGgDP7bkg6pC>S>} z!+3L}_Caj8Dl=r8{gl>?fE1LW7>A;=qDU%UQxRIKngPd#heQ0Nf5!q#$(`e(;?EBY z!~uO5>b`_vKj<--c<1M`?lE0GZi|pIHC+km2XR8mH1)iJ1m^w>|I3_^Yed9En~Oo{ zPI?7sp=D+$0jCX^@DOzW#Dz0u-XYG6#r{hF{^CczzGf|hC{X88w#+yNz&Dv+!_SUwalAaFZDs83$y-w^J59Nj*%KApxb3t8Zzp6@QgSDFmjLd|KY&a#3l9x}5nwdG{=CApBBsC71Ln4G zu=fAj`|hZw(yi|}UgeGj1`$QN6+w_eddCrrii(H~DosE@M8HVzsH5~EgGxsMDN;fQ zDTyc$q>3N`DN(8rii8q+zI~zze6!v^zVDBF*L~l2&RUvql046Ip0ew2@7<2oyi^{3 z^Z3Q1&FOxAviMb~UGbJ}BL6@dwiHkcU{oQr*2kZ(FW;>LG7Q2}c068r4BHyam!n|u z$H&!Nrx^pXfI_&nWw@>89FLh^eRc#jGcz*?G}4)o4g`L!NLrk$5_k*JXNUkm(J>?X zq!z4WJ$Z>b)l+V6f2%j|m9h1QksyenVSoE@_?9Oa3flc)p+?k7WDC*$@1(h_k5p-1vS$at#dO94-&O& zpFuvLNCmfxXRHOT;N%dXQ|v!|a4)m6N2YTTv)+ISx@u5>c6OQEbyT-5!W=ZiU}YQk z9gT={r}U3a`^1Mzl0t)%LX{N8?ImA8UZCufv3v>3_E-b-Nb!lGhI+?8s#4BJg;S`T zW4>=%;Yq`b20LI+pLg}l-s*A31`LCkrahL!3N@N9V~!P)tnYZ9*HF^Wwy%^Q7K(m! z4#qL{i0UnOUTNZws{EraoeL6Hzuh#}v^XI$eCY$ZszBIL`@(zbWM#$ZJw1Rb`Im z&sF&YDZz2Ey}yo8ZC&Pz<`)yZo;eJoZeQ++JuGr|+_ASpE5*t1CqZS4wsWLmi7io- zx0F9L*x1?4PKNrwtgDksc74ut+`TfH0NyI$0q)I8nmrQcpyw z7xvw({A{dq`G_&4^x0Q=WQJBXNjwO&u_=jF?t}cD`k2fIf-8!VDHNN=1;{$IX z_}c8bQHx2oXABW3N!%^rx0L0)Ochs&)`IjEaj}sMu)X!Es?4PWQ14v_|LN^uP{Vl) zde;ENDF!C%2<$YySQ;gE%ux3VC(U(XcM?#*mRKvt^rsvLAyIYwwaJ>4l#Wsx>pHR~ zl*gh}EsOVdJ_T8AzS}$@7|ewR=mjB|BW+ppn|LC4&=%30oSc{iAyp0tleCI@`ZG|B zsi;s-g`-N;dj(B#()PcXQ{yI2lN%fWhIHqQDzO$+b$}t3jFD6q!d0;&84%??->@6| zwbjvUa8$RYvoq=j{+4S`h7nI{?Cm?*X2>RcO=IfWEIy^ej#K{LOE=C&NgV{8Jl=D< zejpv0(95k8hPl^uZytm^vmH+-;wMVXraY%|X|IkAP6yphg{?DmUP10fAyswuwgc4x zqH$0wvo%EAUL(&h8WJTpZ>y^#n;R{FiTEuAJTn>;)07dNRvkgg#i7P{o`jVu?*Vi9 z*5sc#`t|j^_rpDyRet~_EJ)ZkbYxD*JJh}}84VEE=!r;2U`Fcs76Unv!l&i0d?0*| zIGz5ud>{#O>s48*OpP2C6KiygpdqzL(|9j+PC5b)jJE@Rf%(X398g!cN>e;$1NzGR z=x*8(o4{%u zL01e(p^_6z(&UVs7Oza@wKfOzlsTgz_HgH}Ma8UzLwuY5nf^q1h5)e4kRz&|8emmu zCS*S`+(WW6225c8;IJW=op*m%qKE1NPS?uH%46)lKrovpg_M+^FWJ8o44KVVrzzq! zz;{duO?)jKZIP7BzP`RlC96Air!9a-FKmTdMVTx05MBH>~@J3FS| zMwS3J5r|w)SPCZ`s5oSC6@$T)FO5$kxoS+l`>S7Xoj)y#Y;P2b_gX+;AYhla{lcc4 z4}q>{#)AvMpP4Wuwe312JHQNwFZKVax@zjNBCdL&&cWx*Z0Q9&MmMv&9O37uZoYqZ z{7e+(J)|m4N|$$?dN)%#w(~8b$xLNs;MpB@QY_5zPmfu>se=8K9YV$R_biHg03mXQyLMEfVz67L4`<5IbHEQZFR=F>(eLG@x?;mIAAw*6yBMo zWa%2uIX`e8+}hlvl~2+V_B9O#=+h(iF=YGE7Y&gz$_UJ<=J_=1xuvmHE|59_OIF{X z=S@?ufxxQiXuWcU?9x6>kho(Wugo2KJe-rPVGPB%{lNedLEOD-7ZTzzh3Iq<`}aYj zgQee<@|UBYmgBuNC~s=df;4h-ndul}a6)LLFOPa4|>o>+OsC!J>(K5nDP`_(m5+bjydngT|3Dh_MJfv8s6Mo)S!CSw3pOi-O~nXi<^?FRh9yV2fGhoN*!IMu5o zkQ3|7(inw8nJ0R`lETe*Hlsm5qLq18gSmL2m* za3Sml;`sEK3rq+cG88x3b_G1N&gSvWab={1(PGn~p!;{A;2T^<7uTo->e~lfLl-Rr zm$oa~S1*F~Aj$e5vJUJqN_<^v9NPwo%(nH9}W#6ZVr#Tt` zU@5oE(fQ<@2pFW0jb@qP^?R(x@@aXo>Dm;I5P21gwnjg3uR%?4&mHt1=7dc%B9yQT zkxoqKbH0d|cz=x6^&irTiC%P#oWcC6T-obBH|7t9h!^EJKvSihj}NCTdgy_*L0pyk zMy@}iwI3^Mz~ennPA~-pVh^bp@|m%!4txVtubJ8Eb6={vCy22)L}r^db~1`}`yf2E zq)OYn3c%nbNP=dz)Tr?Fv)s~5ejg%g=H=xDjkoTG1gTTK&Nv|>$I2u9vfhh^-H?AQ z*RnZ2Xi^b)hTLLpQr{nDp`kBdu0HJ*(|yW%?vEuE#tZ9@Q-oNKRVcFV4JPgk^46&ST!T3i1ld;bIl739&W1rq?X z2+0P_W-1&gVjkzLzh!d9*j~;;Y3ZqnV*HU_r+4~&h|La3&;}K%ce;NHe|!syKM=r> zZ3^>DNEeFVu^%0DR;TZ-d0XwHsX}qjgJ2=PLDyWtFquZe_WOdzNfNRr990^A!zE35 zp&EjClXT9@$q#1wHYy%~XbO&9@oneQHC@L8bdMw|R+5Qud^I55Z5^2<0Bo64rFs=I z^gzQm2evH+%D3CFs&NXPe;nA&bv%)l4)fyI&`O6+JT^2-z= zUg9W_{eB$FL}=F}Za@E(`5Q>Y#tqxkn9~hPH!OI)YE3Y8KMN6nSAF1+3$6*`=MZoq zF7?IPxw>~#U#~z6I<*QqP69Nq*z^&W?E&{w1a{_IGzBd9^6s*?XgqysthijIb9#0r zeMB)8nKV z_!Ox*a-PR&q-6;3xK51uuBel%-v zu9*QK%X)d046h1W6o`xlr6U}f7?~a&Ws9rTbgbKqV z2QCpJlv;xNLseu_2hTPm{t)ofIe_hA7wEM?jruZ#qVX=|OORzHu_8%1U`rq{7bQTL zo4tQlhoC8tu$LMj!@wXRVG4@|CKoTf>;cR@uv$yh|Dcu%Kj7XVy^xudv@9CTZb$^o z@%x(*49Ho4B>?@{G0hey&`M6xIDY&%z$X(v6`0$DHm{TGHXeOB-}cawWA|j>(evgoh&rp%r011eM zJdB)R%X_t&I-{?pr3H4QV+htKqdhYO$sz*|an zeVLW+ITy>Ve5fXbn?vW2mj62rAq^7~lWf}Qr9vd8sm#{!R%hu!8M~ex`fjwYmYn?% z@1(8|^r5wVj+U?#7?4;}A_sOEQ+PgYWrrKUO(FA#S%T+kf|B%TO4~t^_dikIE@s8_ z`+6@JCWNev;=QCSf|}3&+$EWzS7Wj}p_pja@uuTek>7F&2H5|oSt;1lq&OG*b#%h5a$Mtq zhCI}H3RAHzw)JC4FycZtE0r6QSz{E0PU?pGHE!3JjM!F-wigoM?e`5Gp_az*mq|uD zP1dRHV+@IlYs*^8FEd`6b%dFS&tpqpDiB*xs2xi^6~vR4#I2f#>ETdK(cX6~e%jzl zHb=*Pnv@oUyuOZXz2SH1z8a)S08!AhbRqA#)MO?)c#DsgmXXNkqug&@(qnz6wog#t z9G|iTYt*p}5_$DDX%-$gu6wT%Pv2lbL-IU!l zzc7w(zOc3sF3cr{fXgBy*|pUwP#kOr{4OAUz$p6v=R(B7ZWj1*XA= zaR*-2uzd_r$Eo6nhDgZN?7gl)Ah@u?OLy0O(`UnpAIO^=(yKWf*$h411WsPXl0!%3 zr~7yhFuRA}Yz|n1imYp*_P;Ep>9)4#*S`A|(h#iu_2b<$W_a+rk9>^Q=5_7%-;J(c zkMHyHubER_rmucPrr6fDpr{b{c`hI?fR|ZA8tHxWjvtor*IvV6rLSIvtSuEBjSCN$ z!25Og!^D}+n00q&7%04T_fYRO8K|&zch$rh*7tQcQ5FA^Mww?*uxHhcHdEZ^nc@~ z|9?M88FIuQ9Q=cg_DVRwr93Og5gG4PPxoI~#}+1`usppI-qBJ%y{VYUn!Uz(k@*_a zU2^~>XA2>X3tGFCFEgr3*D_i`sr8B+J=#lN>5YVX^>>p~*~EP`=cc&1kyhaH@mvc% z$@&l;UI8_=v!bA2^+vR@5p5!)o9+zw>lZyM(#yefu6Y`|rOwSR7AKd;fjpTPv6QAP?!~oG!Qz__f1jLPErRqR|A4{(N;y~} zzHrH9g+U$ENKE;K(w=7Wmg?s1?hZk%)ayv;#esHQK-9_YJda)+_%RC9k}QJ)s`Y-- zlhCQkA3O`;Hi9>-yOyj;xN>Ge@M|RITDn?8dfFwWl&q}%Tao8024^4GaILWfX6L9= zY-{au%M>U;Ox~PZ5JJ{i|KSNP04DDiR9~cmMSY<2xd2}Cm%pqv6YgUfVJc_ACxG`JEm#Hc+NRHh790S zE`w?4fK~kX5pvcPS|Ag19h{JQQnHgP(vwvZW{B%s)BnHvrBl_I>ynbiaMKgf12FyF zH*R(FDJ#3Hrif!>81m;=9_Eu9L4hz({v_^T2{0^x{(F||z?t5h_V8g3tT%KM5~(b^ zZjftGrSjhq6l;_Gbu0l^PhF?Amy`*SXB)NAXiF*C;)&VF`-ilGpWpXIw59LYdf+p4 z*H}`d@IKSG591JA@dJ>q!<2bs#=3_k&`nWKA28RSg_SwlULHk6ZI*V!5(qSLaCV=D(TNFv zN3zq{bV(GXlQ^ZTyNk)?c$q19Q5)a*Pw!UOxUygr3ee)q#kTGc4t-si6IKPr5bPz9YD{5!-|$1^?oiQVNw?U|h^v2ZdsSTD^DbrhtVfT6?d zTWq9k|K|o4hO{I1nz>6i2kGqQ<={Yv_6%d-2@hNT1ckjm6=eyxXZPTm`$2W=n;kX? zd!YVfhEXicgw3ygAogYF(^y)73SXJMrDmp47Si)wGje+hJOer*q~h~{r0HeHa}PNf zJA*fJoec0-6)d@{05YOfEo|+}M)P+M=WgFF2KA)a`w7I8=H{-uK5Rg#(F$Q%9&T4m zd~V{L5F#K6aX7AHKkqruAZfQhGX$S8XVAm!`8L$%1U4xN@f$8eJ=Tgz*=zuY67tMr z5{rsNYJ$@J!*?9C0jl6TF%jQUS||aF7X)ur!01%2r;f=rrqS(3@bI+}Yts5x>`Snb z-PP>f1&7SjDBp~beYw=Z5CYbJv9aOXa~8B>cVcHJXIHT-K}RbqG?<5H(Xh_pTbmXA zGx}8es7C!5^tMxu9EYlXNtBS1MIlmXyR!RYK}uPfkc`buu!(SkQAg@!221t(=Z_)U zHvCHg_*1?rD3&GWVw|O<3e@fGNk(`TQVigLV?72Wtj;rb$?NI0y_uQbFI0oa55{3; zL-7J-)Pgx{8*6L#0+@`N;O)@v4o=P&kj9wT+#DdFb7Qo?fGr3OI5DyT)gb^`CZU#* zWkI1Mm_h7mlYUR06sg;jJicgPKCq)-2p?o@4tFLLo9lf_P|Pm^u4Ki2yw`HY4Xbfu z`BwY6u@OIIcLk%{?j|P3BO-R9;brHpUFu+7`fBwPFnDEUc8Gt0^U8s|bawK^#Ti=l zAS3C$1HHXj-eeU=uTla%zSd-NrEM;M)`WzHmd}2epM)%ZPEs<-Hnu>XI;rSdest8wJRjE7}mmXm(%m6TZ^W#qcpiCO-FuEJ*1tVKN*-+{Lg<>R$S_Rb{( zj|m8^OK-iy$JnT!eVDwjV=^d{kAD(Bkd-?h^HWC zwxp2YzQjZW0^=mfJ!7oyoZ|K}ZZK+-Hx=*Z+@;~D>o~V@gS@0&O(o`A+eq&G$cw4> z9D!ynt(r+$6=K9(U|0M00V6gYiYS#cohwKFaT#2pKkN5r`-35St2&H>D-@DJh?i72 z-9Be*`(nh>OHb0!*2OZJ;LZ{%D? z3*_!V2Q!~LC6e<*h>sXk=dwmbHUPf#0IQiXf(lJ8t`93<6WlpA>+BO z03s?ZJ4lp(ov0P@_(@ILr!NwBI=*pTQ53BS;pLpRXb6Ji_$q|C?~Rz$jrG*Q>T1l_ z?^~?2j+g1{n;~tQ6N)-Y?a>9!4(bpu4B)4ekW>L^?!aLQ6lx(Yxuk@O4+nE- zNc7$lW&=52BwjjQ-j>eI3*dlPAq=TgO_i|%sCgE|LP>#AUasBq2H*V=-=Fo)vtJoP z9pmAVR|-SDS%33CQzZZ2V@~*6Nr&C|uhIOO0`9u~{-0^1_#Zn`HPx8`M&=s&D!32t z#sfDwbqe8uY5>aIH9JxQvANrX7(52PR$I}OjiXICXq(LSW?$9*y{OqtK~W(;>>oaN zpCwh8B@niWU=hva+B3TD`3w7t>S|Ag>>jqSYb))uQ4Kwe3lxplxq30Y@&GNa`kOx)p>3c+?d=oqhYboutj>e#pB>t7;R{ zQnJ*AjsTTa6(6k8$7q9JFP z(;HM+F+8%_Qi_ec@=)3El_ z*KS3_Cb`jhM1Skt!}I&Bm?~-s>o{wjl$vUZC5(~fH=*Qi(|MDhU+&w*)wi#OeiyC3 z#!w$&j6U60akl4x{Q5(dmXn)2w^}p@e%kx7^XE;d zZE|#tb)V^lE3OR*Dj5h4(W&MfTW`!4ral6lbrw75dS-Uy6loEj?0Q=Dh^6t}?Zn;A z?YTk|(~&jf+cB+JY^bm8l6$5h?$9Ty_WKR5Ul&?Z<1eo?yma~eWT|h6)cs2tH`TDg zc}_yeeD5Ccy>SjBXGIMsXEL!ozw`n2^qfCuz3JGuN0^506Oud(5fZ*6s3~LH#ZByS zM<;};Ql526q-84E-<|8*xEn9+wM-Ivdw^#Z^Qf8v)nKPP+ zX(fmEZOIGU(UO-ceO_VA4*^ErUU$TO8jwg;%l6D5Rg$Crn3WxQx|CyxKfdyk zyKJ7tWdpAfd^O7|IlwE+`co%YuH=d5D6U^|GpnIBVRbJJ2q2|g{%$}T2s{o@>6yyu z#lj(6b!d$=o@TDJ*v66T-W^4o#q_QxV^ zNxg2B8khmd&&eu>igg>v#k5$7*MnVGu$dF2FQ8ALY^&iqay&K5m+-0raI{v8^x-W2 zNeBvTdHWDO9`;;YF z_1bBtGN}s=S~Y$IA>>>!+BZL~hf9t48TD0?Zn0?AfndGKif^;pm%nNPRbpH|-VVJj zLe-TVsY41iTiaOEL#$OW8r@SB#x=|LhX)i`QLcR@Cx!?Ws*5%TE6?jqZ=0KE_k(5S z)NweqTG=O{p@Ag#gv(sCg$#j{dd|+@5q&?}AL!oWD*(k5t9cR+H`D$JdX}@&+zbb% zej~L;jIEo8O)2*N&fq zs;>^?W}u@~fj8?o4@*vdh@4EX`xkQ3ug#iKMrU>EvrDEQvGk36JYs4Ipam&ejT82N zk~mnnJ_8|2a{CsRw&$4COBOc&PMuW3lrKNK?tKw^zU`&)IY;(I;o?z zH-1fzgU7n!yec77t=RnPhT4;3Fa|Xdx)?B1Syc0IzJ;{P<$Tl&S;Vy~&-6oD?o{@) z5#Mx5Q!Okwuu2j7s;uN(AIzI?GWO=kkg@yz$&a7;1aV#Zo!?GrrCg4h#*qXW28kH> zNRa%!GacX#qDHSoCp?#POD5kvXz9p1vZgY@7k3CB6$yBo!pBQ!l$Q!onGfSKkT^{L zhM*bi4aH-nOl**7ZCqRfHCnHVd$^$HAD?O9q~9qUAOuf zm#(B}-I+7?dVK?g$XKHvum4V$;J<55ztKLuqGM=%j<2@6 zKhzf7z(LOe^nXA4*#=-hf4P2Tn26The_aJ0g1=sWH%On6zvqxX4S#PN`ZWA~QofUk nzlp=&#Nqo+K>q*FA`YTn)h^V3ie}SQ$I}|;)w6%QcJKcH?mG}$ literal 0 HcmV?d00001 diff --git a/docs/source/images/topics/xcom_architecture.png b/docs/source/images/topics/xcom_architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..55339319036a5b65e366345886547ba2663c5841 GIT binary patch literal 57431 zcmeEv1z40@*ES$3C`u_{(ILXnAV{~Q5=w)_5YpWeilic~qz)h|h|(Y}&45TsBdI8e zfOP%)nE~Z^JnwtH_dBoOf8x4CW}euw_F8M-`(A5r0xv2`A3AXS00sueA(`_M$`}}X zU>F#f!#MlE6~k1ew-^{kqz;nm4wf#)W)^S^I!>W-9MPZU z&8!?_M9z7l|^ffytI!;k`PF@x^MsP<#rT;ONWXWvG<~)^XTC@X!-?Xq1Atu6KR?F>!L9N>ly zj&|_x3*IT-(nZ=%-^NtI+6Zm|N-%QSZX4%WZgiPOuIMX#9NX(MZogd`x+n*0YYPW6n_pfuw6?MWP5i}!`gV5K&cA%j*xF*d``fkJfYJTM zOV97V2Xa0mwUT;(Dn0hGZWLDn!$LYTWP7k^YHcsdsBTQYiIQPs7t#C z2rb7QY1&y^gYtHb-|pKx4_Ug1!!00T@5phx9-u-0^LM{W!|toD|8I&jC#nE7~GgmkInHiY`YF8eGA8Jk)tJL@8G(l%Wx|rQE1SBl&q|+z*AzT4we?+8)Rj6 z){a(2aA^2|LW==2wh*_rutuvqr!lV~+|UqQw|B6!Hiz%JW5CPJ1%_+q&dw-uf-C6y zZS=o&db^EqqhDynzaENj10oH#wuC#_xq?A){-!KDx?;LZPj;@^!7cP1%$$Cyg8JJ! zYx1?YUt068wPE)a$g^FvHUlmTcp$X8u|xME%icCZcAo9;J2lx`JK7n-x8H&u{P#-q zZ>r?w`ZrZN=-ZjV9sYwVImJQafWO%h&c7ayFV`J_FR9zpILK?%?R3=c#{H<)2o?dHzsO{heR_ zUn=yk4d!pF;y-_B$oYMhe+CslZ(zh}$|I)-yDYB9W~O4SYI4>Uwhcyh6B>X>P}$}; ztnD03txc@0^erU6UHy*L`1XvvwYAMQ@o^RI;NZGVjp;i&SOed@ix#m5;&RwwO$;sc z?d{FbJP5cf1xS)@zU0@`3R=a#qdGX)et=xi^Z=Sm_~DxPEL7INUS6a50*IXWx^m}W z`#JOn2j?%j2yVXbkjkGy;eK20-*FK<7JxexGqy$%K;Kl6$JP-d6;U@}_9&heVu#sz zYye3Fn6RDu;FAgT9QchY$YAG!l8m?<^uo>!z`}gJx9b|Z;+--ersP{2IKEMM5TWM` z(aI_|`i2nw^s+X6L?=K zwH+w1o2-L${oj+YC>rZOBc^`neYRKhyTlFI_TRw!@cxH7@N>Km*I(BApyd8@y$|pw zXt(s2@IGIW&!5Zt{BSDT4ov=H1^Zu~ih#rW3n>HlpK~hup)#;<1FT||rGU8t_bN|Z~;BSJB@9^<|0CIOhiJf@KZX~gD?dQx!?7UzYppp3A6uz(WFJubaZsm7+ z{C}6-@sBBN&!9hNR^a~mrtp20e<4%&pT#8q0Y3nZ{2Vp^n!WM!JpT7p{&nIx?0>G9 z$L6Vg%RcG2r1rB^m!cOo8LKa=ZR}rtp20UjtD)RsLz0vK;@j`0D?9Df_#QmiWgM zeuVvhfcn3(gFg`j?O^=vDt~qS#h=#{es&D@pIL!}WA{#v-;)lCUKRhq6u5r=tnhu6 zf1z37XUAawF@-0|@(!bC=@$+N4{}>0_T6b2Se;9z`Is1QM9KWjcFEn%fI!Y`q4|aV+ zEX}Tc#bEa}v_*W^W-WaSGZW~TQbTZ-40H;q7_>**3>>2=x_!ga%*Y5jo;BdAGz=QyPU7Dd%SlA40h1@?#)^|dwGAP$`H=~ukQN(;a0ny7VYA}{~km3HFW*w z8?s+-8~b|<8Rw4G{rQFrctFSr?y@ql`B>i)IB;81VqrR@iyuh4s_GN3QtUPFER_TJay%)jmO z`w@@vUF83V*#Wx`;rgLCw^0Q;m;qV`W}+V=Mij>XJ;e2YdRW(g9SHxc?*DRz{^b!? zJLiS`?!&RTe&cW~>5D1=>#Jxeg0slK9zpWUldryB-gQXUcgWz|vIkP6-*p<+ua-bR zP?i5+Xtz(p+F46L`U|w@>xm@0Jj>T}uXeABc2-LN%~cWVAot(+!w5S^!hib{6uV`B zy1VoDFVHu(UjWA|fF&vPcNV%6UyEa4P-4gc2ff_!L}3>0)#MqFM*x zt5u!mdr-pDs>OSRa~VIVaF~cFrarnlt&*;`kba*btyBl;UTqu9sOA2P60aZKCps!A zDnWv&G2wM#6pynB&)(YEaY>_WXdGd_eFi(xkHT=KympFY8wJ`^)ws?)j0QrJl)1aDLg)l^39aYk3CLH4A0alHa>#c{!L6c zB9s(Z0nvDc7vgvn+?GDU3Wlx~f0=BTCSg{mjM26W(@v!oCTVco+5pDXYLOb+af4kYlg3mC28c84!N)ue-I<_0*aX%<-Ne6*

      QrCT&j!7*u!~Wr_1hU5@=@f3# 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

      OiRfuPn}A@+bqQs#6LNHpS=3pJjea3{w2_ z7TCe7$Xq)JsL+-np+2C;oxF`Q{*pt;S;MOJz>@qj!9P*$FMBmg>pu`NzCFqL$H*P> lKZN62dNfXiWK8-T;oNJ^*Lx2R!9U9K>X-6m|DPo^0RVlS2%7)^ literal 0 HcmV?d00001 diff --git a/docs/source/images/topics/xcom_periph_timing.png b/docs/source/images/topics/xcom_periph_timing.png new file mode 100644 index 0000000000000000000000000000000000000000..da29f67dcbd9a6ef80447616355c8a362e299408 GIT binary patch literal 115177 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
      nliJDTC8(vC42v4w1M=mn^6)iKM z-JZP6{(-xV`ieD6u>URt@?#Xx2!ZBUQ$*tGxAhnP&I1N&ZVIzZ%63dB)WsbiI_f^$ zW{b|vu*6SP4YjfSm{5Qmq<+eJs`XsBcIOU@u=UXWLA9TxY`lS%yPL~Eg=e1}Ut;JC zXx#rZwlA?XxdG})*`1bXA#zAKPOr%;H9qXX&=|cQEH>F%;kK&dA_Y^!F;RdRE@<5G z=h?EjBID3w{jr#%<;-Vv?TT^Bg9=S^kF*@`<#4vcA3G0<-dUGQ{A&aH{jzBJNY#f} zzv4>WHrJevUG+P}lN>Tc@Z)!KVtL3im++AaR1ba*5{A~RSp#`b5) z|4Jpbj2ok%NKxwKLaEYVP$Tr^KFlAc-@3_G75ZOerio5EVx-m|PV*ppAO_lI2)3-1 zjcx9CS4Mlk5Vv7{Dl%967rq|tT&_Ao4Kd$yuiul>g(}k{zYn^^gj^*lFZ`B)zx<>j#KUDeeXa2KL}#33m=650dlI z1ZACabLNk>q%Ktq7)j<7O^|)8_={7TU^9!m-v|;qC+W?Yixs@wQbB;*DE^5DJi71~ z9w-R9r=?RroU0;lRcUOHzgRR=Q;Al~z@CT33G%`;E@5$C_DifTjaltLC2_GJ^wTHo z$4P#Ro-GzuKWaACPsZGkRX|VRJ2vwTPsC+H=M=q}vrpaeaS?<_ons2+76)<+#;Jw` zD%&~eml;PrE`OYYmn+D_LT24=2t>U&xp zwD7%hxQ%#)i1O9+80U(Sy71G%+>A4z@S;)XHhI_71VmP+2sM%M6Sq|W8-+k6R+pm( zd;*d&_l-MElVs%NM`Yg2&5ik}q~I+UbcnOMOfB$D(u&ie0lq|;I-fDNHqL%?uIh5D zTq74XrrC}D@4Vm#AXO3f?AGk>HI*oWvaT!#%+8gf4e!yce@#lEI2dbE9|W&^F;Y+a zoMf~e7#agwU6X>;j+KQOEYDoSVMK`>S0!1_GZ9Q&^?z9eJB$B*1HLEAd1jkGt~fT4 z^Br~rF0J&XYRMP-YAF7GqXH3578Vv|6%{hkoNUpD8Ze0a05Tig2TbB$VLnoL3*%=>bkuhX2Vg* zsk6XD8GDQ^{~k$D)+6^zx8l;P9a-C6G(DtV>i#VZJ+x0*5Ej+ccXfB~wOiNxoq`7r z@}E;~n1KJf-+*_HP@hC1_scZ#paw)*Mf`rtibwH0)<4I~2H=K&ekm+ei8X`F^kir; z$;FG6{$we5wnAtYQ0;ru)=l06n$wK*`HKIamti{jpRQYxaCCrZ+{T4h3lKsd2|wHh zc4Uq?kRo-mlMd@rWC{~l#IFeLAz);FXuPGP;}81W`c|Kf5-QjySYnq+oS?w&H};hB zq1mja_Fxwh#+x6==lVh9fsH+x@EkroyLfQ-^IYz}F>S+SY}FXrgAcm)eyOZS$I>?N136WY|YDt%djIzrRsNAor-; zvP>i>`)4ehKYAn!M;vhYR6*D0!%lii?E=F>E_a2gJ6>le24l4y^?DhYNj4Q^PbhMM z1=Q2k$w% zu@d#h``bDQ>xkcJexS+>Y3(AW;=VL;aL`wfS)5D5Q3OaUCc>L0vYTU;OfI#&4Nov{(GPrxZwQ|NQQt_Q(N zef*zQ?w2oLa_p6Z3&Ke`l9v$?54Ot1K`)DF*wV7I*H(d!r+M9fZfmv=RX61@Hy8Sb ztMMk;*bh(oYkS8G*_u@=L|qhNn^!Y@%Y4DuG2oqN`Aw2)w_Z|6PQL2|L(>IGw~FpS zv(PcCNXq@ws{Q!ml>yr2TyJ;IMB`U;rp4c)UK^i))26g2jmM*dp8{bgb|Jc4sOWv&=0&0~;Ez56uJ+>`oZFE&FPUYh_|% z*J`apnZ-EWq~n!UR-B~vCtmPg%7WGk_GSZccZRou)?hWrHX zoG3w@(^JHj=LbJ8ZMpGRHt7E6A5&Be3a#{-cF`}{Kls0ni({R;&R*9Y%p{~@=)Trl z80zxFi`cM)sm7V+9u?MKpO4jtMy|$dP5vSSwH!(Q8Q}V_e)in?>PZKE-q4BOH2k^4 z7irIc?zjlN9OTx=Ezgl~z}x=oKg>VMH%93|gh9K%ibC`&2><_F=I}jo!r)91 z&Z>qyq4YY2v~$huC;yM{=)XRG(0P^M*;zyC|30w?BcZHohb8*g;`lo}XF*-`zf39e zs|Ewt`5wV|IJlCCKh|GI?v9{)q^nJ)SYpP z03L2A#j2gt2qzOy{2%>tkee%qrGELM9V6~|zVDsvrK_%Xw`#Q z9ky?%bx+NBvkiK5vd2x1U;Tfbyq9-t{U|4tWVT z%%x+;j`_eQ3qXj@z~MWRo@DVp3)j7+r*{r^;FELB0g;GP%`UiE&?6_)+;cxiE6ZX5 zm4$Htm?Z@O(9caUg@giOE7Ar8Q_{%ApKyA>qf!*1jNuLUdt&debnA@y0c+g_Uk>;{E0 zh|Gp*EyRw18J4NX$np>awXiU*VJq>rspJ6ir{+->n}tw=cSuM`Yq>C(ZFC!Muk{-z zKUo}w{oM`)9}}{C*VOb@IvDj|xc{eEnWn3D3-TG7gAE?pB#ny71XYm#mMES_#*cdFV8aOn?3e&FxdSw7#ZCxb_y=XO^3>{v$!JJdXvkRK){ zCPPM~)=cMz%z_)4T^c#7(K0>PHpG~U4wBFl5N4e1-{OsiXzpA;-WXI7ipKsqd+eC2 z(s63~{}hCwQ}W$4j}Jb3`G+@k5R}ql=9l&$ zrBcw)cnQN2983Y^_{z8<-C5UxtoL-w>f=v8T4%JQk&hygYJek~>Y#DQCQj-V&I(dx z1a>(7sU5H?eyagKgs}tR@~!wHc*wE)RKb5gY>NmA-rZapXOMOiJs6c*a!5?f8to)l zAx?VH5Wsl=FU3Xhkh$>s?Yq9{$x>CSVc{7#p}X*9`XR18V!pc=h4E-IZ($TizMlmk#IJ2Rn}_ zR<2>*+u|5wH4LvivzQth{rQ(!EJy)#Og->MJ2<=%N=I8LZHO}-mW9@5)%=jsZ?#=~ z@=O_pQD?QYsEDHAM84bBN)`1W94(X1&+0mpNG=n}d(|NXe;L#TRv7c`L6q(8sprm3 zBUN^XiTBEu#nOXLA)>m#;>3K{7r)GGFFbv_rINTcPR|021LDbX3`4L|`wOL0YrCJS zbrgD!)9?aAvNt3pUaEASvJdS$?GMBNcy+Kp8V2ExDUxbHrvNNbIl^B5K50e4qm_$w zVy$|82|y-QnWvNRrig#PNr8(s79xtPWMa$}IDO={^ELR?7KYBCMp#KKo6Du(7u1X_ zaer_SmnHFX!7UtVrCc{ii$&dxGo+K1oYq@E5SExys7+;NQADF^%oCk#!1FQ&pbg-n zaAEl6s)0cPWvQ=g+)JUbX+J)Fc=z`w@%MoVxD~Wa@+4TDk9GNE7#I=fdc|xbD*si{ zL67_{{GxJ%45<7>?l;D6<w)TeGeEVE`UEV1zA1aoPxL z>o0gzrrEwu z)SS!Ne=afA$OotFaL67u6aX4gWZ?x!+lOWbY#N&`w&AgJa}y&y!Bu$LJpTd`MsEB( z!Oo|CV2aTxdk9ZCgkSP?E_fpqb447K@)sP+HoF@mb8jH@EmI13UZG%Cky;$##*a{H zJBO65XcP*WbD z64eRCUNlGkf?QmYV1Thfgeif@;M6pk3m6tiH6DD|O?ybTbdx;Wba9m4q|P+x5gWi# za5ri{GZ)7aV-E3?(N>BtGi7zjq~c7f8bQT@L_6 zS_-p%I`4k!35uKbTzz9asepAI%uxVl01uun{dv<^Z1XDhuQD~?!n;3Z#MCnOXZL6A@j&pi0fT=d|DMh&it5ooZEeY!@l+3 z^{Ulj@-^<=qI5cf8mcNbPAScgLYGrXfasrPYvs5L)rvn20nBN`{%-qzWE{7a47~$` zy@yo((>?aKaRo`OO(QW_35USvY8>DzenueVbIX>&cZ5i*nT` z7pUli(=3E&c z^r{^3U0!zzMbndoD)eLW9(8k~mW#57%`)6_IgtV8VklhcO&iY_BD8v+-mc@GTH`7B z3H{amO;{2pUztT9VXjP$eR;)8IaZYJqi04yMzP7QZ}+Bo02)zOLY}|pCaH1MY>oz2 zs`$evYEm@5J{s(IO+w6QNSQ-LPxFLy6S%d+fP^8AC|WAO%BK_RJ*?yD75!2Ebhj< z%F;ca$~>Rp!LZRfJIof{t)wGX~WqzRAl-fDhiG-@}D@SDz} zk4sy-in_z%mD;Tv`m;B*w3QnFt!;>5{Rcwtg0YlY?>=d2VbkP!p;O%wL=3TZ?ZZCM ziPY;~X}%o(Is2l;v|sC&?3odzb&sX1BWCB_b2$&vBA|CCo6T&-?{CFl2{kM*fBD-Z zW2R%G&2{31rfI3~e)__iB)0t$g_glHtya-az(S8vM^xy%{JSS`$S6Yc0mr6T4#F;7 z|I+2hn3g*OV>c&1;Vw(W^^B5+UnbLjLY941Se%P%jfjxYIKYc?fDmCFk#6HmcWM~c zakb9*{{8!a_VeTvB@LS)o7oSgtUHTl+JQvw{zbcQeV+FF&&BkK|_W1OCPfVaJy%m>5G zE1|19dxhKSACl=d`sg-@#Kct!c2q&A(=k0GDipnc;b&HHVsWuvhOsDMZ?j@s8FUTu zQY_2I!XO}0!ZAyE^ViYd6HSs!xrU#(2yRu4X%yeEw3>05_JcI$_{o#k*R&mL!q{Y3 zCmX|*Zrys#W2$hgai%kQ8DOCj0iwxq8_5*4c-Bp?r!yTKBWAD-d(#kj6P@M|Zt%lR z`xUM%ds*Ia+cmm>)aHa@!i!X zbNqEWpI_LJPo#i8#qnomi-T$fQ(#i8Q`=XYeRk%JH9np$cG zuEetV$HcC;=`1UrI40=mTD3v8G=y&*FP!x>6)*X9!NYp13u4Ssp^$ND?md2Y;xm#) zYV}n+>()B2W;w$d7~~-NgTlq!^0KFv&3tM!RaNU+o$MJUCI7;e9M`x_=eN^;+?a!I zii+Iqz5H#2;`mJg(jm`5aEue!3cm5U<|) zEti_c>l5IyCkamHP0l`7dYyrzqq$ML1E<+gx%G8+dL3qG#b|Eioz&{zRB&~ z6MLXxe;;dW{Nj`U_S_#944+8T0_0LtOo7fVgjJAd_kNy$rTy?`Xkzg=*BjNIsmvP3 z5}DMgw@vYu!#75r%HG1su^GG;F~lv>Ra^3fHZNlA9zOwOo*Y?=fc=tCPD1{x*UsG@ zgOW$fqfVI5ZVc2Ajl{bb3$0)!^nKIyyKCw+wU~u|&GA;*{g!`OPf7bLe55!LJU%TGBwD11WSMv#4VOVLim0qAnaFU=pBnn<3x34nJ|g1d2s`Gb=9)$@4rcD z)l*(5OkvnVl2Ax?OoN@j0U%l;?y3)GfT}Zp1zD6ai|n*ua(bd!H0r*(J2HMrp&e-% z$vDOP(7;2Q!#*_1*RPYi{Q)4E*yFhEPyq@5Ws#W3Fnh1}-Ub>&OP7YeH#&^)Az@3Z z4E>em+tn1_rgeu)k*H^t${Q?Fu8~(Ih0pCAR$mss@*;9oPBgY*^7h4Gy@qs^4|m)a zE#%2vjV0UHC`R{ASrq10JU&CE%c=w98jHue)2~QwFll$WD~&l{#6@`j4LL{z22l6p zJFB4BViQkVMWWfQqb+0PR_9tedVu8gp7D6_?^x#69Ll~@=_#2M7v9Yx&8!zqA2`M~ zhEUlE?HCcT$g)VODg7sMAbpLfbxT`YC2(8EIc>XK(?0H?RidcYhmXXx(D$geIK``f zE|o`_OkA4E+GpT;WJ98I*h}Q$ET_eP1|D)yH5iq;%;<+fn;})}9X#_n-sze@uY)@IyylejG%iye5)igKB!fB$+ z17-)x)GpRbd_EzdIFZHLm|4DhLTX8BV68)HIp4j>$df>o1^e_7+iI90I%Qa|Al}Tn za_JqmEg{K{P0^x_hZW;Xy5+C2)muDsjiO<&JMHXXSkEIrOP(zGJ>Tn>MMRk8Z+F}| zDfm0EmhY`}EG?%yab1>onz=b~g(x!`?H&A*YpAZ-ClyFZHG#ywczMupsR~Y9$ z^s-4f!e8k4l2{)s&6$kg^$58?_6%_>O zFK%DIBkvy9fMM^_U?fD>{^LFX@Yrm?J3{u^yfga9Y`T7c?A^`ERk0OeCt2OaDNt z4vT^(4I(9ky@N`)>AkV%-j_%F0BwqO*#7GJ`2CmN=Qy+b_myM&Su8+F602q~1pj+r zP7Y_;kKH7R;oe$S5yS`M7M~y`!NvAT1b`DVG)tf=tpio6J=4c_9bXS+8EcvEOhdmx z7ih_EqiKGms;OoYAE&S?>L0zf^W#0k#L$`F)itw~rDisf1>}Q&F5kKOZrac0?*ye2 z`~L4N1Y}!UD4&{Dope?gA-Kw2B5ldTmg^Fbx_@H`)3I|Nj-P40Wa`5Ss^vQrOmB`0 zvck72ems`x9L3g?_%;-@YF(ItD3owJM1z-ShX&X53{0ZW82^$%f2zNSC1M`)lYM7Y z<3?Z2(32P!>a6Dsi^a~BA~l#YHnJCo`B)FRjg?VAGl7u7K2zXD->7I;o4p{?oosxu z^dX%a+KLX+K*j{+<@HOHtYPLoxHxgd+Z5EQj*d6tBpIP|4{n}Q{Ll>WMY0LXS4{G~ z&OTq`bT2sC=nRyqqdldmknd%|)8CK&ZPwLug8d7Q`P*RH?)0v45gU@3u$lR55gi^)g(7U$sJ|Rn~hQmwX^^ z(J4NC$*|S}Y#!X%Kb_h|4+@IhZ!ZelI^V*NEav3`JO!3Mb)|V$AG~Qq{{Jm93bn%4 zU8czSMHyx)+2clU5860q?Iy)aHsxvF4;HM2r%Y$Jo7x`rW9-I)e*h%*HHG^CEaaKc zR>B^cQetyIps)R-9#>O|9i!Y;do;Thd$nWFvTz5)n?mb1M?n?Ke`ihH>}kK!`AAd? z!f{qDo92PsY)w`ik;yZFdr(2Lg|9~=(HPEOW6kj?SX6yZb9v&~Pesi1`FTV!N5_*S z6Mq6cYvW#yr*B6M!%K2@whYIAG%5?vt7vT3>#6!X6}W5o&o@4wue-ZaWxSCQXs3!V zC~{QY5yHPoDojUS34|m#+?U8>Y1E-x6_B#k8IypBeEi=pUY;(oAv?3{Wc^iI949|< zd~=wK`4$Jdwjrc){zRB%PO)P8f0PyjTeA(8rVp*EIzhI)wo=kD?O$^2fGCvfmL9S{C->;AvBadHW^ z<2~=Sj!)*$QZp<39Q<)7cCu3AP4ZYs5;~Kkc`mt_w%A$Iwua&(YRe5sp0b zPA+gLk=-8(Tt2&VMp*PRrm*a*Nn8 zhaGFX|K^9pdAo3rlK$HY=F)tHv!|O>x+ISmL)N5lFD~zqjd}J+FanJOs+4$GUxS!m zvz@K=&T)7e{(PZ}(zO#+u52aeS4WpW^0hVzjY#Ys>2+f$Eg~{t?l6T4zqpXTeCI$d zDE|-qlvoi8haMBIOhGeAH7w$Hs)Zz{f!do)Hk$;`-wJ2GKbLCkEH9K}|6F!aIh7sz z=a%p*i7?cyXH2zR7wB95t+amwkCTOp(;(l8g5>G!JB6*3j0XFx+nf|cFM_i#m7+r3 zp1-Mb)@~X!Gx^!gNM&wg_W}?r1Uj)fQ`Qf(LRbpH{_`Qq+;E6U$KK}1XEVZkrZ&1S zx*S?L$K>0SFPc~0yHKXsy@>zWBVPn6)nS>3z)|pXp3e{FKq@Huj9+#ajIH$M(MvqI4M*^=>~m z88Sc`)&tHaX&-^&UGca(jsYqbK4YEs<{K15LXqj2*oS*^Uwd7+yx*hzZd4WgBvz;W z6-v{HIQ3Ywp?At(Bcu>!HhG}~dI7lf02Lw?$|SXTX`~^h8usoNGQ!4c1vzYR+@-GC z1$nz+xeya6xI4cTmHVfku)Yp@KD2NLY862dkzwhFEBE`*(>&Nlbyea?2v2R!y0q~1 z#vDqIoyrk4ac>&rYRWUUaRx1x#09mWPsZlK_%G&aG`X(tl}Oz&mD(kRoZJ4y1DVv~ zYHL95`Q5i2)YLZZ8r3xpt_OuKoSj+Q7t#b>jw6c%$K~z<4SP zHAn4ru40n8*@sD;1c6(YRy4}3Jb}8mOux9J>oQKum{h!aw)K7ZfXac)KXiKbn@=Ax zy>EqA`1?W^hM45TyXcLJ-&8w$M(vvhA9kzGBdtpYLfBh?0lJ&WsgBQMmf|HU?@N7!IommyGiQF*SQh~i5s|6C8gD(MC4l+xhhFufYKxal&m@mG zE$0J`kVpM~V-`*+%DldMby|bPEv)DSRiP^01JjB2K`M2sk+@9M>=2+Sj~-Aj(MX@?$ehEP#BhW|B@a!3*Gd`hLBQ5Zsq+7F@0Vzq5F?&i$*5Kd~2i0ZbzLYk7B z{eSd=t{I`5LLyf0%1&gvu)DK;Z~NYyrxZC&^t+P2m6D(9(DQ}jBfXVj)1I`WZRwV- zT-VVHFC#ZJR$C}5GJ}!65uPKgE1#s)Uy)Kzg#p9?W~@ua-94?Y#QNB^x-Tcp>{<73 zQT3oFdALK5&lp{$_do?c=jz<~niu5%&$@=SxvIs201(E#oI=6mhQHB8o>Pt_!sfvq@TB(3USLz-!7R3Wj4?%!Z}0Bzf`1B}cLT`JhYubzGXue(LUH2Eo2 zd?-~@i|v*5w5;}-jthuPVcSWMg(32Rvs?c{*N9f-l}7r~;H_lcf?F16$)rD-kPS%Q ziqCy4|Nb}=S$BAr0mCu}HkNE-6$+mz-lm5Y0*4#Pp=9l*)S?JGsll8$lACKrraxWc zTjWBeJVVmOTL@ga-JZD@DdkAu2f_8qqQZ?kye>u~mI6s;Hcdt}^I+0+D3F~I6Nh%t z{}7Zb6__LCsDa}1a&jnpqPbNYgTgs1Uln!vPmM~N9T`>E@=YLs<`uFbJ zh`#s~|3oTW?Skkf`xeqENp@Qs8Z~CWH9s1^IbHjjl>lY)fdu~Zl1u!%Zyk&8d@s6! z_LewI!NaT5fookfms1LqjO?$YL6j)rqaGwXd)H~f{73&yilq&~!tS!K&h@5ff}s2* zrr)Y{P~VhW+Q55I-VKw#QsZwg{N251Z&#de4|`Q?!lKgnXhqecZA<66@_Pc6yd{;^ z<%5o#^H@rk14PzGf|RCJzXqEt#x>4(0WOn>j|0a*k~t7-S@7M` zX-9{9YVEktr&u^WnR(~|=QExN>y}LTR`tBLlV2pbM9LYFr2(1-pxlIPBOEit))WFK z1V_y37#ZcnP_gUJ1$v~Tm2SeupHK35zbm$fp^pyzLm?yY>|tBDP0nSJB+wWvpq?46&QC;vRu^f=|j zq#%<(;U6i7ecMoWQ_fb(eD;5K!<(bP!7515$u)w)alFPCK)tJSHCs=?wN8y?h)9SNPKK`8Jb2U9?N}wj0URM8oIL{!H1J8g) zgzD4u0;F>(dnb5}m}ek+s((?{XOiE^?zn-z`ilj6D6huo{Xqg-J9ylygnM%rm zQAHJ;bazC?;mPkILcBvxgYq@TVDm_n#R<^tD`SGX{P>(C`4~=>IC+9^Sz@tX#Uezl zsD{Z;&6miT&|EPfI1@-q06#^?2wo6XMjOVTF%D7uHG23qf>IfW!;+H;)umz2PS)Tz zIox5m6X!7Yg~#Y_MF}1b+JN3<;=#_^#FL%AWQa;hL_(-=a%K)}I~5PToGSJp7l7V*do7 z^Pp^#TaOjB2hNDHvadW`cZ16e?_Sj#2pR!XogP5G^q zz7X@BFSuj+dQ&k>mbnY~pJ zyMD}F=Z|$qpqPcRdPaHn=@m39KcJL7Q0@uayjhSiZP>Ulv7G*B9v?~bZGYKG8t-kX zzGM4?GCId^k3Up1u#DFTNO6*|afrgphdO>4gGU78DX**#U#bj}>t@RQ*%;0LlXaSh z&zPTe6taS5afUElT2k#V*FV$odS8Te|8fCj5H&yCOr3xgscECPb>nc}6`l4*4l}c} zwa=@nc3$MoKKmnSup1Hi_PoQM9Eu}r`0cFXuZoQu`6WQI5rL}j=|9)Lz6>2_Y9AWs zm2cdtJAZKT`wI8&A@irAqN%Cm&`&4dAJ)WQra9py;PVwL_a5wCn1gDZ=}J&YF$vdv z+2Fl(-eZM+(j?@(c!9GXjACLydNIDaQfsu-2-}327NQe(V~nnRuj@NS41#jjtS%Jy z^H`kR^*eNBX(d-hZYhDd{MyN!cJrxl=ZjZ|cXqtvE&I6BUX`b@TG`AvfLg7_a`~@X zB)pjR*USt!z5qEW^0L{@AB$=Ly#nLQZHo>R;7eF=F1;}I%b44w5p&QBn>#^x>jZr> zTW(bwB@4^@mv4I7Ia!-kIolDoo)k+cHq*GpabtX60&GfEcEm{y0OB?0xzUZy#Js}A zvluO2vSk!Vdk;s!OYhr&z9HUyiD z6N6*Cl5ZtM6qvw;XA@~I3Z4HoQ#U6rnUAh@8S2b)lyRdgeNR;qOtz!$Fm;?PE)PIt zP5+dPu$RYX%U(Ni>?Bv#U%A|&wMW{ZN@i~j&zi?BX~w9O`Ce7!B+mu63j<>7iK~|1 z$Y-mkiK=$!D(DXSP_r;C{}*ZR0TorYZGob+U@Jiy2?|9isI(v=l4FS^BZvqn2#91! zl5>F~Nd?3JN|c;)l3*!bTs(`-^*!Okcf8Y4;z0asIM5^k9efC~^g*oTi zNA_g^y%AKRTTanuBs}2C|Ln*o;+*p1mfk^kEvR+Bcp#sKJvxQ3@S?nr3oBS!BM(9l_+NTf#<*|X}1$3Wx z!MAK7f2w+@k=p%dI(i}Ky^yN@5ESI6KTPA`W(XOySz|;5Sb~xuulKEq;@qbJquaTw z=K2;4T^nmDok8n z<&QH@HSGI(EDSOc_?@L`l|OlUeU8=zP*>-!ofLoE&ul&S#cHrGkWW{Q;Scef%x_W# ziHq2yW*8gnbnNUOpco+HK*2z8p%PcQa}xh?G=Jp*q9go&XRK#{s)CdD4(2Vo8TXo< z%0@;w_n8&v!TdVvWjy9jy1*Ar&CM~ymryU%zoqIkLYQilcc`VVL@}H((Y{I-P!t_@ zZB!Hx63MVo6%rBsxD0CbbJ`Hn2YQ=j{pI>0K*`G zk(90nMDQcSAd5a*9{XnlZin8FZ@>S?Y>E`)w;IZ~hSZK`A37?1B z`XahQx{3_fmqi1nMIMcZisFAdWG?r9kQC=|-kePI>1&viP_^0eonLjD-lP-WhW;Vg zhk2QCBGM0XWk;2sKF%#VsewttPh^pcHR{SaITfAP$opX(DOyJzEZfyf_Ml9BzI243 zn9$v=@foN!0vsIVD4~ZR%a5T%MMb&T#q@u?QtN@HfUY_<%gbn01!#xWdi23|Rw4%{ z{#+P#l(=m%jK3x*+U~<8cB2{O(IqiWO^L!4-A5mgvXVLQ;buz=VrJhjQHrHqQh-Xo zW&@{G)cg$_nefp4H_-NW`cZo8&KI&G#kXXxq-4;l+I}q8rm{VyrU30lRb^M&H7%)2 zGW(pW2Yt4Pegx??Z%2B6bgPYR=RVYg?M7heN!^g+kypr};+d+3P^*A-+5DKg^b zTsj8&DjuBP)F^&5S^;-ip;zxCIZCnOlFvOc_GJ95nEq7C(ix7h{iPRXCYaYZZcK@a z4YQG>CLXhUhlxeH%!%q`kVfAqU7oWv($3kS>)NWgVgBe*j@^AQXlyv=N+TN0DAT4`=XP_uAo6 z^9kwjd@%WSl^v^-S8+M}kfZD!H=%v`!}a##T}KDKbQKgDq&k!v%spsqMd-*;{Y`ui zD-JTyZ9&UN)Ecwea&J3bCUaAt(tXqE&LgM}Ed|L!n90bIIs>Dx!JwY5&KYb%o)w~y zDJQEWHhGGHE<(WM_KzZJYU*z2=FULpHX5YaS^+H7mkVN3(>qD#J@VrU&^7Mm=Ka$@ zH<59RsaGG7XMrp7(~XYZ9x)i@W`Qxae|TybRXB0Uhv7`ea?=PKUk;!|%db`C1WvEU zjqKDX-)Xpc9}VwEFi$*IsDcTX59~=UcIWjz2OkOVHi<&JXU~H^5&Z%?#iV2vf$=pz z@WGkw_}=XCP0N;k2X&p9{^UN&a9{dNK6@>*shiQpk4QV_qqqo-p_l~d9Iu6Qb!s$+ zyZjtSjv1!spu-C2_zGYGZph|=*p68^i^V5tIa%J)1@T83Djw>9{o9x&5CXf`Vif}Q zlpH78(=~w_oh9`{U9sW<2sMYB-{1XM*Hl)|a#Yk6T#kpU7aDH$C-sR!+d+i|<};gg z*CjFH_{$@}$G@l+(&p7CwMZbnO~s$d2sE}^neN~{yY!9)@WPH%q=OlVTG{$o&FSmG z&m58{0=P_zWi;;d78 zHs!$KvD+pQ(zoa051?r>C%*=E>Ye%)IDR+?x(-eNiu8`G0IcLd=&>Z!4%{U-owwXv z+P6bl*wKQ5KfhU^`Nxa@+&UQLcMmFGp(+AF^do#jT}jlmGOs7AR-S@fPP z_cnCBIuOB_ove(f-&9a#OL(LxQM{CNT=^vvxj^ZDyb| z?o<0Kj+!O4%QFccnEq|4`zfs#lii?#8Q&j6K097l z03>K=Xt*hsk&g83o&PzX+t8m0_)e*Bl10(U$+!6Vd*mjoa!=y3cc13M9h~#m#yhxc{Nk@NFH7UT(TekZ3i3j$IVyuxJ?RN&Bq&upr<<#$POS;c)ABLSr2MRo z%v|kOIx60&uYq5gEv7H@1wzw%B{^A2S~k{2i8r;T+$v3x>~e%VWaoTi_i{ ze0BxwH{rfP=K#wECIbDJiO4HGqO9t+G328<+BvcWj2knQ5p-d%S{J=K4QAmCXiJzr zYhPR_7p@vq&`i(Fr0uK(^FYrh5tb>XZ72&ob$MnK?Eoee#6tHLG4d|Z)Ri9fsD-%Q zw}g*`$cvz2=L5%x4672s%wQbo`5K2_2Dr=>A?8VR?5&y;Z?8m)tt<=2b_YIvnzBN^ zbnD7@J2vw@>sTGb!3vg_mGdvl`+$i(C51`bG5Wc0|KoD%f`HhRV(gZ)j_`tMrewme zi?$l_8t`ih>~M8Aazku)WWBo0nPUKpPo|Tv@)9+Ald18y0S=ia#EE7iZ^zRqR&|MH zYt!Ct04pl~vAhH<1%8R>J$c}BP$EoM4IX!KeBoenCtC3 zcTRz_&YSyAWACg27a@gK1I){@7A1@vrPwf|-uhhM?c2B65y=&OpyMwyNJ=UNiKoMg}5Xj1T|L2-fb?CZjQ=j-0oEQUmze8#&T?}vuWVikwu?L`#@e7B;-=(HlO;8Ow`-NaRxLH%^SUczRc!r_lJ%K4 ziV=!$EDtnUP275O!(G?U_f=-7ZbU5XyO*l?AT%2&NejF$`XFg`E5@J!UozTbWN_WN za8_o&co7vfO?55Qw zfeX{<)F8PYj<70aW$Pu^@56l-DvRAn#n-Kto7m5GpN5tiuRl!AI^$f{Ehbx&-?&a| zrcXObY<-M$5!Z<(N1d5CLU&b3Ddg&#GhR_gLl}Q2qiyMB`1#;M3>p*y=+a9{=8Au= z+9-}cK~u?3lxd~!QP76~0;*{tV^@bY;LkfmW2WBE$!(U>JwyB`Bdh2u$R z!zXAmvUaE^bBq?~0P*lP(7nIr@{v#Z+#94Mdw&_4e2+F?=cN|+>A3x`&hYR{#S<8i zpU@tC>_-rX_5A1c8l;&`3p5)i6WOO^;qf*xCgw7znDj|ei_l=-ANU`a@vcY5$X*~^6JXlW3A>HS}vpaLDmM%YKArz!V{IJ=N>A3-)-j=YyWTbO{bjVdUw2Fh~NMAr?1Aw|EFjAZ_nLJ3$uHi|MjE$Z;k_w zAJBH03YEwMJdvsVzkca<1PZ03{4N5E;2%F8NrTlO$N7(+2S9xP#~;YZJepvB{O#w# zpNR4Vg0s)D=qvtI3lD06%jDml&2Nx$i~1qC-pc{|=@GghAS+%6F|*cXI8Z4~-9JuC zkqzCUil9;w7ad);UIW$KTFPb|S}qR^yn+tVem7{aRPPX-I2(dyPSe z)|q3+j{W|E#d4wi+z)j_Fpr2iSbF#C9&YU}%crgej2pU))#FvsGCpxRIk#nHK^B~+ zL)*o?kpTSO#X1%V$1H>>0+Q=b>xBfsvcgilQs64Lb-`1AaRjdMbxI1?F;Q#%4ZlOL zhQpnwlDPm8#Zl9Qb0hk8^zk=HjBGk_PJgAP;8=O!_FixSG11ITRA4g6G0apHY#U zcZV9g$gpJ3yjOJ@H(;?gUD|^CBqMw54b0{rh>^7>9_B4Qar5TQ-z8!( zM4E4gHI(JV7y-C`r&1n?0{CT&wA>H^LNhw>yZJ1?Y5O@kx(|Y;!RZ9RNxy?xdbQA^ zPajbB0f_%L%rG)o=J`4@@;v(=O)kl6^8>tllk}`g<@2eU-~4xOK1i!T`kE`jhZx_W z&$wp1HUQ`69LlO%{mUnnJnNeetpk@<}4DM>?gs+0+mt`gu z{hRS;^xxh&eI`It?72PaZQdKb!O!KC;)~KF?)1z*QK)jCb@0~CYZc3mRdEDLJTyf^5FYNU>x$D5 zRm%U@FvRI?&}Ojf9Ls~W2ORquIcj{uH$SpLvq-Mv&ZEonS5+Sle@Y%nK~p70vi$WS zprmgD!*tVn6j5ujMwcx2HtWjGtkV~E_S2@Bta&txT`@U@}RM5!18su!zymu&w20~%aIYISTG=MyeB7EdDaY@{~Ti~Y~5QLK8 zAS!fClx&}rZ^GHy52ouiM5^m8jO_bK*o#`|36Ewj=!Nc=5d1dLnXAi3sG-<%@sSjS zV{{}f3(GovwWN_$oJxeD^e&Ox7ByNiBgLd^e5MI#T$5_j}#UIaI#DK zGhH(ON^8jWcYcJt#-%H-4a&fIRIFI&Xv#HGg8S?PZkxto%-@O+V^i)_c<)!q8*>Wq^| zk`p6u(=~xfFa|@==~fkp&Sa07oHTJ>7>sI-1I;+dxmyE|fEI zvP?@(UhsgU;oS+xDJIMr9WOE@PerkNw#?S$yf-cR#vRhJNFpN5mbAgtbRQy>5s-S= z{S>Hw>HjzaV*_ikb8EJC`6(K5MN~SN6VBlao^}C93Xfye_BYRQiYrbvKY!X0md0>9 zioplwRZ$ysZd8S&&ODPhnVReG)U|(S$pps=7Ne^pS}^_WSMJ!1^Q5(#VTN);RSU0d z?(U@)xOBD#xpwm+Q#EQneYoVuGyph(+=8#d%iuvuECjaKS4pshgfrj}dUp4;I%jPT z#TK!}MJmvHx-z&?0iwgP!uYC$ohz7=(BR+%_890c{@@34`OkMRUkh_W!p_c4x3H>* zc1d+-o))w|z-M}`| zX~K6V_XNlt2tRrhe6PN`rsid1Ad_dkt{VUneTNFr&_&7wV4Wvxlylv@#=_HDlsI$< zLu;G9r@b*7Ptb}LUuj7ToXyVL%OthbE0wGN{;obIz<&OH));g_U zW1wVuLGE5gt1QrWxy}1K+^J|$_nuC+}zokclX)LXBk&Q z^b3J{XZch$b;{zRr|UZsA?37o2l6Fw&aPhmo{CPPy6bLsV@txK%AB+`FXm9jIJ+AA zn!XC1rOhuNVw|Zn*XR{>m#M^Yxqg$DzlQ~Paj&zrhO1y+nUxFw*mvzAS>@~ADl^|y=Kd3OT z)^me!|NC)R7zgDcPplwZ#X`n)#?JqoPDJz7T;5OjZ8*2C6#>d$E)oz6OON#O!yl>3}l>`V6z(!MEHxZ9AM z-*SL_weso#F-sM_ibXZE?i6}!%10gi{QCpC@+~u@7Oo{{Y@Ex!d0d52)*6{Br}tK~ z?WfEUP%OGd*93%1FG;l|$fYfCZm-j8b_6=AEQTGNc9JhJ)DZxNipodLb)m|632e_# zrdXmS*RcJ4?uV=8ZyQw8{>sZ^sl*$5ABe2EFJO`wzW3x2Up}_Ev-;p&y_-N*^vThU zOq9k_rpWW`ujv3*2t8iKq{q%kf-J*oT5kPiAL>RrcNCMAO+=G}R) zi6%xKPpuRb&SUQ5ywTKM&KF)jMA)k@@NRPF&R#lS?;kdDzxsM{zBnXWE{pEAsugw|CCvo8W+gA2745TSA z4`V!?R8|J#3I3r1of>cwfAt99{WQ2=iFf1gB_zg=<)SE1ih|7)+>*TRHE^LfaBnTU z1+L!&bQayLBmQW*KiBrOhOLpy7d;qUX}fqD7JILo7$E{uQsN3lQfCYW%c?`HBVjDE zvf=@uDfvUgt_7Et&r|1E8gkan^X>hW@lm6JNr<$vsLXwa4t z7;TC}XZF7TlB;?Di%Re0Lc_vt-mO}**;Y|a@wj{m!+-$SbfJ@V)TUgjM5-*8J@dA= z-Mx>Fh4>_dK!#`BRa_WefD z^E1CDyllcqsA)zM5MU~;&(~2yrIm6gCVARi-~el5jL8!vvmYM{t{2XUcRtj}XRO`0 zkX5F8|HGM>XT=1KLnZHVgQljlZg!WUoZ>5A1=zGH;#1;c6`InFMbbI%xv!ytK}w51 zb$S@frm6C$1dsCT`S$bIi&w`q^DONL4^(7*&s1P0+VK<@j_vSwM~r(DmaBReIDW1R zt6aY)Z`%6IhNT6$2WR`-XWg~fXeahi!D8-%}=wccp_Ts=3SfZNT&6|!ZTf2?_I|( z{aUg}HW{E(GL~o~ZQ!tVYR8f9pCagM9mzWxBdf64z>;@i#q`|s<-D++Kz5b2GjT<_ zi{6s0Hk1!{ZyYIgWfV_wfyV^wfleooQdzF!SN6$Wr?2V~(@v9Z?HyDySAIeCdy_Bl ztuxS6tZkC*;HIW z3AKJ6r%=rw^GS~4rbjZnP*%Ou4pmIg#frqDXhkL|+lPv4^SC^Qk`;q5o$IqVex#ng zacZ{?pevV#lmV2a2yxGS3rt$%r>Cb?RaeU>(Rb*YR#pVejsLvW62@ZNVjeo%Bdk@G zd6<7)XF2~txcfQfpj=zhjAmZRzB+0pDbX`8(UTg=%DSU_wc6TdXa^%EdXuH*kUtFD zw;uB4HWnWIxh5|+rP0KhsQO&H-sUP&{iF+DX(&5X%sA1-;KwHZs%#)(59rmmC@OY* z%b@^E+kRBBT@mNTZ#&A8j+byy(yu$T4{uZB=yqPZj@m)u=p0hb@ecqW;ItQ%a>!Bb zA2}|9BEZVR*feA|y~9f&{`GKCN|=1ShJ9EpBp}c!W|3CW-1{-?3{fizgi-A59n#uJ zbah0#)@-kQ4co*LfL~)z&X|AZS@5Uxy=91TGxI z^rsbBlC(?%F$Q0Ee75H@=S=O6?#$|iy{Ia4)41T0Yrig@(MyV^3C~t}fs=SI;#Vee zEB(OX0^`gko_cfpB2fCvZv@K2^xZEVH-1Cmyq~#+f;egDR_q^jYz5jbJYAO4EBhbP zb~4`M3*0a6&#HJ!TbnJ1$bXNqGz4m^rZ-k&$Gm(~rl8>9s)K`w5VCEv&G9du`y!j) znV9U8g~gw^D&7v;w$gQtdV=TpK&xu5xI^=dimZzy!Dpi3>~m%Hg6_3m z>Yq>!8b0FbYLE~REbLJ_rI6G6;~Onp97nTrztPvMX97YMy}h?cdG@QbJz8kT%&~C! zt@4>_=aC;zx>swdW;gGe=;Lk5TFP|nbZyekr{+pJtSvPn&meJlbK!M>VN(mrR=o5|s^4LHrq7^KHw73VIz%H>6$0I5>GF>g$4t$@WWyt5gwe5yWI<)}~ zj3((R9Cg$X1{L7Fmpz>$iwRu!NP}2E!Gz7BKq53mYb#!8dcA;Y4(yL1xX>!}_uf)Y zaPxU)Nj4!>(%c~tBtr9Ok|j*g<<@%}mKn7U@DBUCe!(q~^Zf z{4~&rst^K`6Bg44#}u*-2N~{0QV8~>EfBNaxo+UNO=ekSSgsUB?s$2-%{c-thAa-BmNDHQp1*j8|R_drqpNTHo$TOi~d zQ+$mfq4sT#-+J^408DCXau~|*U}8$5IyXfW=~_(Bl0uK3(kl(_>`FeToQ2^K&t+E0D#%f(|ty8Zaq+GwAW~Hg{Cq`q~!bV0Vf85`6E7rAgV$V6;*x7Jj z7OD$FN!ygC8g&13-#J+oFu9}eJKkh9g?}`!cZ8P4bTXAiQ<$BKdr|TpWRIm;>}KBH z!fdEdabUy>l&Vfj+ioYx=AySWsi=P^3d~ETc4$>Fy@~7{%s+t6WIi+THIV-OM~?UC zq4TnLRH4x^DIaV*^K;>sn4ZKG1th{QEr0A*RoL`F1BkZbWP{i8IkyPVa@e zw*=x|j*rvOOerWT(oC1{UwT()TOp`pe%A~O@PlMAp%z}9n>p)uD5e)F>xhv%wCpOe zQfjA^kbNZ7rN@6X^-nzr6I2f3zl0kJ5dSu3HC%}%ao_Ubhu2#6@n{u|RnXIrLK)IRSzK)>-I9vF z6Z4uZwMRn6LR}ml*hpudP7lN%?AcC1X-d3%I5bC&rAN%Bb={WLD^9*=8)aVrj}ms| zc!zll)tAoLeyInaRbGB->uvml_xy$2blWzYW}=mNUk^U=*f)M zQ6pZdD-TvT%U)@jC_VrDK93~pn5al+?*roM@v5pE1EsvBk<#UQ{wbSx=cdU~hLgTx zI$EyM-;T4eTUy+W&JSZWUThJj7*D;9ZftHCwvqBbOlj;LF0z)?6(s3)@E8}(&8w5AT&$#evduCSF@dBMpD_4nCOghv`HQ&@svm(ySJv&4x9p@_QvNrRI z*cE{frV*EQ$1GZFRs}Kzf$$Z$ows?gCkwxCRY<@c+AFB4_KBUv%aWJpHG7!Dijuu{ z0dRQjr%Z9y>=f(A8tD$t2@20}x8Q`LB5#$rDGaJG&j<*!x-Us<%lTewUP`9pC@={c z`7*F0gAbr}JubH#>wT_)H>i$!XY+p5CT3`O4OJ|-FLUlfbkWH@7r{#fb2KFdc1&Yu zXXmds^EsnfW8oySQaL``A;AT%$2}FoSdJe*Bp@l7?uAy;=t@t4q~=|{lz{h3Z88p@ zI(v`E;ifR!*LN5bmrWK04vK;h%kk?ivd`+MsSUhBu@?!4Aic1c3RJPHxZN=CIB^vw z9y>Z>v!U&P`wNM==UwHOS@|`IH_o;(ST!=5*vRPK^Gt~7T|%~fNGd=M5`oRVK7HL4 z)`d6q$@P5khC7&tB~iwi*oqerqZ-d~*0(jwPmB0ljyfjik;Py0C$2@y8l`- zwYQ*fQbudEOs4TrmHc&D0ODnRyMyAxr;gc_w)8%}CXB+^M7CFsBvVK6G=k*spaY2} zlz5Fw$=o-lNSeE2qH$aOb!H>o`Y(q`*IqIz*EQB5ltpnep2NtZ?dhM9-A683;Gc+z z)#z1r_hu#BUai@dL2!63dtSfA)W&ySY&3fe^uWns6SMtublZOX!;}If;nSxTB>a+# zPR51=xI3k`Ye?pw9AsepERdPDdXzqt<<kO?+f5$2O!*0vrc#+mvs6B>tgayIHb& zp3;6Y>q;n#JW2HhPn6K(OUvkWQ>yp3+1?#5xpS_|k-a_8enRc1B#rSlFMU_Y z@r{&M+L>xqk4t|bxYA#KDf@X@sOPu=`I~OGHQDn_&aMwL9^~dfz9T6b$}(O@^ov4A zoRidtwC^F9HsP6yM77H-h`(aYX0+BqqJ1bDxS!{E+sVQApU?34YUvyW)NjJ}OIL$m z$#W#?=}p29h^4FSeQ%*{Sy^n+^T)8_XVp83)$NKAx%n!Ft^vnDSt#me1b_s8!3`Z1 z6rj5S07+9)GY+{>r8>bLj}$Lp+)DjctEsC1vDr*|g>h(mR5p8zGo!?vrPQkI?YOto zauVKtw*(PXBQ}GK9A2z_o^mC7zRU6Vp!UgcKJ3swg)p+wA0NhHCgK}hu5sae=I^?p zpO+6C`##PoiZ=N&j$!NUJTj+xQgKktraTH{@8j++&`Pcxft*pW>_k#VMmtgsE3ubc z)a!!`bkdxV@Ja{!iv*9#P&tk4NvjBnJe9!%SF5%)?o4lud-LKPzc&POmpdCnegwf; zg6}S%qqQa(62?Md93-c5X{7zMhVlk?MDG_lTn+0-xt>@NpN3%L?N?tby#rzs9+^w5 z$TjsYe5c$AbTxn>(xrqI`CPw=E-li1K8IV&!h$(fg(q~snpt0}`=93;dx%DbNq9ZG zskMU-3tcak*Wcc1o9)vRH-ysO_5h{Mtp*-s1MmnKZEp(aM1yc|R@Lvq4Zoqvd>ghZ z7FNrD-yggcbU_%)Q*+vyVsk8J!ZP>V-KJcn z<+;NH;kr&(MM&E@GkkZR70JJE$`j>Er_=k$qO;I4>b!PoXZ!s(Or^dPAl_waDg`(0 zbHxr|l;Q5%gw0A8OYkAIU9HpwKNpp`x1OJMAO7sX&c(sjrV%JCOd>QiY!IxhuF&2j z{T0Mt9#5UO7sMf-#)+J`phF$Xd{5|@7tO=9Ys@m53rD$<$Qcw+LeR~3AUdXL_4XYG5J_&K!D;APv>3p?SE z`xn@Wx}1zJliqzoKkRD5gd40g=<2AQN@iyb+e!z&^!2x#xRd{F=f2RR{t&teU*A8& zSfsk5yAELJB-0elZd+vglXwn4O~epOyfl z%EN63PQ8QBJsvW8#RJ>Q0-Vh4y$j1xfo4MrZrpzxJ7{-a^;4n+QuW+<#&6wmQz=gK zT`xboc?V#47ZyKs6;@9AQ3ENCM8awQP(Qglzi4dlLisLjiU7!4u+LcuIm(FvH48mo zN~9LF)9`mv=_v_q1eMBZo8QeWK8@jmk;J~??#Ocx>}sPh10kHiplW$lbx07>q&$8* zTNUlAl?<+T8o!krP{14 zA>Mv%26lAwZ`>4rPD@V}aS;w-YFl+Fp_O?kdcD^s5VDPihTf9eSx#pr7pguG{a$=y zl^Tt>$EVYf7>`ozoQmH?;Jh8!zv#3x0w zj#?+!B=b-0>&lxsTjLbk*Xbg=>)hMIrMLa5Pm4V^$^UF)eXtO^UG9~*Xp8y|AMU5o zZhC@_=4%QBC}ezmJdXD>N{rQ|mtYR*B+0hkBaPuFy0?UR<@ScI_1p_%tjQ$l1h#j4 z`PHg4F6SG!*l=*Bx6V8yuh-cQ)~dhRK4OoZHRTZG92~zwi4t*p!qNSxKvP&_Bd{66 zdqU^H69f_sF>Ds{Rn>+}G&T$_s{dz826nY*I_`OAL+Xaf7d`ob-mHf%H)WTZNTQtp z*bCqNT43wq2=q9Eq9}`HDPN3J!sKoRsSs*o^bl7!#`u-3w;mu5g_!XXd#L3Y1oC!E zs{9+e1vK2HG37OZhP@^hjSYew^FDSinXg3B4yb$+rrg*OiQE!*nGZ?2o3mI!JLNFn z+I;X`C+7mm;961o=i}<;0X8<}x_u>&Uf8d=Xn0a>-m0?PHj;f5{<2%k0<~{o>xin!^Q6i>{MW6 zW~)MPl|xwsED7O0%HF=fu!j}ZLdxjjClyk+6h$c{@-%Y_KU;>1oERbH80mtJf(W!h zpWzgq*jKkR=7;X!U*a;KS$05SzF}=Vdka<4(FdD`B@DMD5Am#Zm9%Cm>sILGcjlZ& z7qopka@9s=w%GiMKee!Bdr=9EJO}3-L^?+f@$zgu1`}@Ydq*J&S-jBVM-3qNB{LVb zifxnUUp%&2qXasSD(=2+RDDmWNcVa1i&&# zCY)zI(%JdSsioxDa{vuDV)9OT1|VF$5Ek`x4Fl8u;qNc} zTcSggh<@J-0#LN9EZPYtkD`wj+DRTts)@d_L8PaF5edSt=xU!5;Tc&vDfF_62-N=|w1Goipj`%#vGP z7fTb}f8&wGmEZ$`u#KIJWMW@kUF}Y|$pYLA38$RB7^V2Ruj2d1xz6!L(HoqTSfWBx z_=77pGHzRFnN8j9f4MkzxEj>hhjH&=G!dVg5xTBDE$W}y+ZmG`9X0O$ip-5}B5B9* z7@-CLJLNP;(FhRK-Of^64o^YA)Q}`nZn+bzbkDfePlhzLadyP6(ulE&WR}{GEf|n; zW14#XXTDsFURPE0)`i)<5ELOx)izrJYKO4&(9O;5htn=vOMHj4?B9aWIq1z$7`BRT z$dJAH>dZFFeX7^O0w@h8QQRs>T37dgSd1mu|Lh{^FfQ`QiW4LDk4%y{kCCQrP%gOx z_rVBGtIiQqgP%PLHBMk$d5)V~Zgz$f&BKF6#S2MrkxWUfb9riDw4A!7<3J)z-#EvIm9Re~7K3g0?09zFc$fLTB1;$^yI)V1O+F?D+FU%!_aJC;{VFP|itAWJ%@VTc@`% z`|eAb4T&el0COvhRYtc>nxF*;Ktk%zf_isIADY6D<`zkNma-4cnQLSbJqBKS7CS5} zqF^eN+1r$Rta8N`PJHvwV{5PM8w(}s?Kqtd)wKTDw#cgM@L_Gq{doB+e=(#SZM;#!Cdvy5vuda0izgWOM{E=Qp67KePREEK<84tgOJu~l{?Tp&Zu-oF zn1D~CsSY|9bBl&@88k`^Q^x(Ly4iK?8W%0|B6X~ld^|*pGDS#S&%pt+V8KcfuKfaN zB`0#Qt&-v$Fnq{Y<$3O^#L>Q->W_(ZXbrOLG`V|Z*0$w-M4{m0{^!H&sJ`p_$Gt3{ z`C8hPua>80P$uJ}!F}2tb`hu%Ll^`I3tG{2z)6P&S(taMYwfB7K^$Vb>Jp(*qg~n`L4O;FUiKxcfN2NO~1w?&9p#z>V^20z`$=p^~-p zmY&!0Mts3iSe*aeEc~E-?MQ4#YT1hvmApq&%vst7KNgowyME}7gEguzRiYp0J+d{i z8b)Y}@Pv8>Fy=x(bk%i>&=&TdA4oF9qM2^LEguCwe2P9U0 zZdG(f(#;v#$fRMj>YES~&!KkT!s3>yWSWb*dDF~e3~r$G9)2#Rxs(W@<$H~c{L|nU zJ+4A6MUUeO2M*Mwk1=kF-<_= zX~bVx0K6peKHh)aJ8#Z;GyqTuBNBVEG+CM7Von=>sKF4IQM7j zVA=tTvCBKTj{-raQeJiJT9?tu^=t$mXYV_YfQZ1+?CpKku4NM6@?~_bf^|TUNfv)ba^OKRU&Mf zG5_hj^#Z!sZcN8+uAuUVhd|MwsR%R`HPQVA`hVa+3&(V3$f|#9UYWr2tJM` zVanG9x9Rxd3G$7;qEs4Ir;>U%^Cv>s@fDSm;g%NfUx_~lIEm)+9&d+;B%}YLApsfN z+kUE7ix(|=uj-3h3OBpi<-3d8K~j&2mu8&}(?3cQS$7!bc z`;6GISqKTsPE)S3qL92v+Mm3<9iU)+ubv;Y17Cw(BRl5^e35(`e0`+$LVkX}bM@&E zV|jURyqzob4{KXlv2B>Xat5O)MbOt21N=2$*?zn_nO^Yj?OQ;O;PIFgMPcEJW}x9F zrRECr{zX5o-#nqyRdxpj&7km{XGSNfn}iO$mjZBJPiTmZq7dP^s{uC!_I*4#rnWig z2DYLkQpr^cb5hCDx8Us8mF(iQ`u5Tpn;C6digues_k&jpkbr@S9Eq6dH!}`M9cEOhd{-lVfJ8z6NeoT}Y2CoPL!I#6@TmZruqv z<4;vaw;QN6&oKH9xV5|Z^6T#i72EI;@F~-6p0p$1s{PPv z^QPTrQVjV59KSpRjnJFFt{``F7_}G}bmjj|aBl7$3=f#jn5GLthupXJ%ibemXH|B( z=IfuSqo$eql%b@w^bWCL05nCwx)%UWeLp97oPyGBWyS`z+WQL~JcL3)#|Xf_Spus~ zH&9ow!5p>toUU)HBEKMjy2+}~uGI#~5+N+^E#?%sw7ai&aTJf)E1^^79odz*H;Q0K z5V}@)Ph;ap7<*N^CIz-4xtnH(7Ag;B#zF!H*v|S`+sWqdN&kXPOt}hLy*7m!uawU$In&e83X#nWuh5kF}wiEYn^Ut8_1fT+c`6ENrwwycuQ zcX|pf0oCg;;O6i{?{1xqra}_4UrE%4Z~BPLC@`6b+Y#VwfR6`|?SLQ0S?+-6S_koh z+gCr4#p8M%-xKXqIwtnIKn{93p0j6vFKK|5e;?Un zn6x)g2n1K0qcng-QZNT9e^oZ8gza=Y&rGS|T{OZGT_kYf%>ali!GF$n6oU!c%V%=R z=k${8LZ;#)qatjgtpJLBOik>JR8*Ap-|lJMwsdEkh`V2;U;X;kuZ-oxQ)}2^uY!k{ zMn~}~4e4ORcJGB{_gPKVs2!p4o-JsRno%=WFaqy(}Cs>3Kf`4vtbFOV_FqUX40K?Xaj zT19N+j;@xM^4>*n2Kuf!H-`P~vK{OY#-E&QPl0(VuvBhQLyR6fRIWBk6HazrPR zuEg8*U!)MbtppW)qYKIk*CkqeU!9=2V`^np#8}~EX5RN==<3?s%bhPb%e)_%+iKoD z{1=dW;mZ+|M~|9oYj5aO>`UPcv^|YwA~vTvQ6W%Y_>ri@VZaOoM#WMBwu7eC&b34a^$+Qd?Wd z@s>SWZ1-vY>fHn*!ZWb=Axc+nx=LzJC9=T#2rstwbT(o*_56cspzvh~*RVSDHUJdj zHmnUk6_t&Dh~o%mUi=&dS}d1VM1~Yn(wFb1dt?$i)LrS?`A^i0`Q3` z1Q-5(3dssZTGyNfVFh4!c1Ie823*k-f$FQ^H0p#0C=9&n8J?sh)RYjox|#P-*~V+- z&w)+1|J66hdMhFAm|>fJ3+XuJ4BY0UpKdt9I7@Xy0~1{kv`vw@c=6)7^)6rn9A#jr zzA4;yN?qH@pjXco6jpMamJJC&7?Vub8>#e1{?`Q+g+#kkFVMS;v4t|qC203o-54zs z4>HX-bA+A-V#q+}1fha4z-Q&X9JryT7VNsU+R>cY;C0bn(&%9ogVeUD!|) zykh?$pvwBSn~VMR5}=^ERq_9WsT_{<#NGfzsmj*fLW_t!J}a=6<3aIH8V@tj<|25- zbabNdn*k7=AtVgpJa zaVaU+Knok=g~>`UIOK6Ep@=)U?13zXi<_H6!vUIBg-qkaYk~9jve9!@w;c#^z=V?p zERG>H2^euN7e?S9G#}_`Sw%hqH98|Imc?^(?{m5}(2iE4lVtOnEKY=+g6c8xD4E1f z@W)2Msqi@vO%fv*R}pIS!Bcg!^nX9}0+M1|g3g@UY8m&>?y|+L$3Ga=Otqzw zA7`AY2dbt=<3Bl~M-F6u*)E1XrEGlwOs!r0`}H8dKO6qP5^Mk>R+60SkV9TSJpJ3qF*fu2nbwJRekrrIL?&=7#x&uorb)a z^nt)=^#Ok>dC({1UuOnpxyJtb17D5*55rzPQw3f&ybR12Km=))gP1A^stK zkvJp=1l+yX%qA#N2=2qf-2JZ~p}UZu@3rgDYHn;CB=!ViS2&ztMa71~oP9<0&&BZI zplL_OyC>w7&wa0e5kJMtt0W)D#sfjw?t-|&_)iY|1rJ1#VjZ_GnVgpP7NXa)=g$X2 zVL)gKSNT7z^D=Rz8!Q&giP6(E{EvG^)8#?$qH;zfg+qj0LDbU|IYMm}bDv&3o1UZba+ zY;QGu{#|L8Uw^^Zq$QzxwE9h-lz&_tFw&QRrQI{z0xSQhhw~h3tBuFTWt=t55`%0x zW_yuVbUH0JE;;!s(whjjKb0HHWG4haMv8;+l~A-M{)XJZ;BU~t8EoR~U~g{iDgO2uR;TPkH1(%-=ve z&;TGm?A9}juTyG#%YnN4F)k6dN@U)KF_M#AI&?`gF_PTzz!C%DQ0*}E%Dd<=cb|@~ z2!ur9K`V=|j@+Zw!&y;MN${5jz|#u-BmY{xiW}L`a#~q(tuhOYcExIEwW0_HA&CRI z8Kg5HFp`Z_tGSH3h>*46HC1%)Rzn>^(;nr{g{@OAXEgQc)BQ-PT~<~fI&tzf*u2nR zKgj+=&(L*&uciUa3uyrHj4DO@G?FpyQ))`e zYm~VCsj0l%jQ>RthtoP+{5tIcLe06?r*-PUQIVA`wx8vKiRJGUsR=Gd^?nemfYT=7 z4Rsyd{#yYE_I@lYsD=QSn1dZrYY6PIQaQklA?@5$&$$1=SLK=skkt1i38W>3k^2TL z9(1o;yW`o$^Fi|MvG&=QWKRy+fX&hiTfqTzN#|g-*2H zs_wv55+QJBgSM;KE)^lKfl^$r6bk0YWtbl_Fh6Kvew@^iK1G^y`0^%-G|CAN!r*7{ ztDSk%l3%lp7G|5HHL`9!_6cAv*YCJl9MK6ypI#sGLD#^X(UJlQh%55{e!xj3_dj+O z3w+FX*TQY`siI|gp0H6M7fOD&!0dysFSG@{3sXQ#Dr_{a$VE#vJ}K$PSnfX1Ab93H zCxI-8OE_z`C5Fy1AZjBUAUiws-P}30EJ1b!wR=ioc;d(b?;C>H+ig|V)9jqZPfl*% z2WCA88o>X=dSDY6KCmjmcdKFFLm$_7%s+74Qk$)|KRdjf%3w(@=kXb_3YbP)#VZC-n6HKT~OiZl% z>^iLgaygiQIaa!OcKLR^GxpQh{5(aM4FNLrbv0uIE8^ zJA&EkuyMsT=nL?pWF9yDpU+cdG6Yzu*We{q{qsD?7@W^>-@y_V%4y}EDf~G7RN9k* z&@cTXb`;E&_N@l`!(gtQf2jNYKb(C9RFv!2?;rvKQX(J?BLdPOodSa(h=incDM)uS zDAKKzfFPv^NOyOK(%s#i1KelyoO93p-|xHMT6dOfy{>s*-g#o@Z|`SsUk@}jphntb zShWBn&DOu=?EB5QNg9BVK}Du?VNi2HSwmy>*sR|69|=CcBn=v^XJ!TL-m1_5Is?>u zG5+~Q912xdRGd9D%U}Uq`bVey#f*Tc#Q`$|u5uC3s{u73YI(-$;MZ|0pS)u)WuAZ+ zBYzGMe3jR4){&I-QBhT`@FcUL_#*%i9KkMUzb3a5z&@&L+e&q}$*Ds3(kjwwfVt_k zJ-N2{KmFc_)w>m{ouxs2;3wuDz3v5N^4N7) z1PUk#z`hzTes-RY1c$SM+p@pZg<4DJQ*^jKBqw^ldLO8!i8jmyakR1Ut|CkLgjU8;0mC7BcNKpqa00&fTgbo1;W5bJGG*VPef$uWSUpz zc2D>R=7$d>;h@YfTQX22E~M)f?tpKgAoNYO$b75SpW2HN9I*n`7Pd-8TK|wB@`)ZA zaDGI7zlS7xe>0Eo>5A4B)DoSF{M&Se)HeJ;?z@nk#qdfn?`f${b>`P0rD?ZH*BPAs zO_H|j({Of^Y2=?IAi^$^6BfVvCU=y=xgR`9+KgssO$wMfYY{ni5-Qa4;@xldN}DkY zVMC<6bUo<_U&J`^m=#h>NDz&fuDgPX%8b^%MUy7Wu<-mod3}I`qFYk2hPsCM_+uaT zOLt}k%#}u!k&zJ;QURRt6wt4>Xu_c3>Fyj9nwnMUab_3W2V_(A?cd7-i4?E3!`mmi z*>rt<nuOK_@Gl~`T+ z>b}R+d3gGPW!2K_9qJEn>T12MuWV(eUm~IpYb`%c9xm&i(c^M84rqGuGEJT64ebnf z@(NXXs<5+PUYuTAxo3sc9uMAH;C(uUF|jlsnX&IfLbf=?9+osZ=%P|ub6uisKS57g zbG~saoLq0+DXLSx%rZI{uFA~5WePfylZDG3&5$j9dd-|ZAWy#d3vXSL3YbAT~BJz z^%kUBLtnR#-f|~jABM9Ce7t^O;*YqB^Fqwb6)#+SE@rY^_I$HzbGH&EPI zrORx6*|gJVxil(p4o8Q=V7O4u1$;gb;xm6DROTf7w> zaRcJro|06BcSKPSsQd(IL^+@;VX#FYYlFIguJOuT*_IS>rUoZT;un1ci1t@sGhBVR zr2d?~*pr>U*Hc?~a#Y)2URf3;YL{hPMihCD?ppkFdjLHB$rneN0c!WsZ}GC!-}G03 z(Kc(P>>K#RQ@=AF4yy}K-^pw7s63DSu1}vIl)XNHQ$)v3UvME1_w_pEvH@*B|1fzq z6Ud_5^Ns6#r0p69Sy;zpzdJa?_Gl08Z*rNwcU1IXXa6G%EQi;~*@}Ac{DHz!ytn??!Lvy zMnVOPRsLNeW!?kBHFvl1KmkjI=xx5En8KMP`kL_|89E#`Y1m@%v2yXM*kWXt!ofrY z{k53;2^H~><2D{5c)nd8r3EX_2u=R(JWh2gy%LA+WBK zO1GpthRMJSp3euOZ4~IgdlyGMnD#D~kt#HG*jwqo3pWbEP0aS4aD!JnD6d}iam4aG zn&~^(72f>Bjl4-t!V=;l5J7>#Yxtcr!k3FNm^OtU~Tw$!OBB*8J4or|b+N zV$YTgE3NUWmH9MlmgB(igYj%pE6P-FM$6X`9@IFF`F8h1^gh|4WO^MR8CpTZBhsRHvLkbvsFhTu4zdXfWOkhVYrh+nljx*J>ckIGI znABzd?zUNgzVQ=-1C>Wg}3-_kC~r8<-5qX68D_$ zmW%5!e*(Ev!naLM7HMf?9z?&mX*EcR#&A2Tv{*59jjJ#yJ@7tfU)W=}xD-5u}@ajPUt_llu`C<*oj zb3s1%4qW(+;Et!e29U?eqMrCfL_-U9P}^3Qa;|@#4eoatHMMIhV-#kx@Ja*x4 z@Ps4DUN6VoW!Q-PrZrTLoqgwq{GjbzfR!|<1%X; zI{~2!L!hla0jNG$)K${X4aOAWuW=8r;E;}L{K4Y8ckejN`svKox-2!x@V1og!12M% z%uEiY_$Wj81LSPM({X(*jUH^o$LfX#;5%@!ZM~AMf=W6#aDxNP1OMf8SHn&$6U!MX zA3Q-LXUkd=xfN&>rAKSn`8ZD0{MH?MIr$uZIC)Pey8((qb6>1lu<0~hZd_2}>zV#% zZUNdHYGvs-=jb4N=M4M%bF)AJK%T+By2Y#=A~-%m6v=ULHq$@d@hQ89#pk6N3eIjMec|3QUDRBO{@4NX*q2gXvN91K_0 zjuZ~_JG$|F=8?|b$10;VQcLeJj&J<5?ImZ;M92TS8ciI}0r~D#7C8j@l0x9hpmk(D znuh7x((i=Lc_7)Ht1!gZpLOrvddB9Fq)Nc!G#z?u2y3Q!L>P4YKo!v$uqz4?9Cxlj zQ-wftUY6xHHZ>7YQCTfyM=1Zun=}Pu5Lf}Xa_C3>P+01Kh1mA(nyv3!eYlXv!F{orJ!p1=MI@mwk z2rMQbfo1yw#!!EqW2W8pA32GypzrP^1*nvNlpIwYQL}e!8^I%@Ar`2xwy%6rL zO~0@o54o*q-JOeaH4G>5Yv2qC{S!>h!yW{jDuP*7rb>v;Wpv+bP4L@^ic(T&p!_4m z22&ss*@IVHTpZ#JPA3YK^TJ?sg3I=toXLcaEmyM7HuF|NIWLGefN3-{CCR#j&!TdOrg9FbJGns+tFoZ8n zgN?P_o)mzzmc=W+3=7bvKB$O`>!WOYGNF9?$>z;9#+_j6yVYOOAGAg5rR)Z8V99#= z^ndJE+8lk`$^KKaA^cD>F|e zX$cE8i7oQxgEkspmvpWxeO-0rQ?xrwa^P=ld;U=g4181aqOHB$b^)J^Y<+e-BJnsp z^8DOwbEa;lp@bF+jRXS^K1-CLzF@X3sI$`>|3MGY?~HmV0!)J3@H1`g?v*fuv<{r< zfX`6N@}JrcgaSCNdcQn&=?CdMSI4e@ytAKv?6=)ohZXn;(Nq2y59gd#O@8~d25|p3 z>lFQDC%GV9nFM(9(hAi=xQf`8I5yY*vu9Lh7wGF#o$4+5ewm*x@pD8>%R@_~%H-=- zjd_OEp85w8VoapIfdNxdNlz~vfIBEaDMRChoY_>EdOEd!E9KjOe#s96BHv#|kB;h9 zBz{)`tj>NUnx~pV;ynmy+qMA9VGO z%FH$F$A2!qC06mU!?7N-9zzd}l+34B7G&w>_YYyZPsl>XM!R%0kvTwhaniJ|fgM}Q z@xsL9!T!O)mK`fs=xFV=l7e_Eh+Pi89J13w z%B(-y8%SfMmii;WkeA*;JxXC0d;e9QdGpJS4gr*<^I$~wu85I`xF3&iDK|+vj1U4`t<-ftiWex&>BJt zsTJf6MhPdOpalI8L$*W|e-_Sn|kX#7*Hlo%s94q!M?+XcyH>7%R}eIJ4h8 zB^6dB(Y>Nn6@z2jDp2{f8TJUEu5|QbLRNhj)um}YGo#5&aCcH<5=N91rf@tJ(pzx~ z8Y}z_2Hf{MP){OaZ3(6iaLukPllgCkzYmrKlIaFJl*MOgOu7EqTzgGgCpO?15r) z5QdG@rz_DrzUFweDXeP?V?_EqW?#!P)bh%zHEf#sA zLBli@dF#<0m#Y?m(9JD#KS#a%W#|VrKrhZup7Yj|kFmQMY{3Up8$$#&ma4$Dlj}=pME?OBP9M)E3qPBFCVDB%TrI zvlEt!OF)46{%q2fBl%;M5qwD)2!>do(x~geaZm_^gk858C=+)TAd-QEIM5d@V^7GP z{4y6f>-sCRm-_9bu{8`QB59B8i^P5qZRR8|irIbP9#QLNLPEtFlUu_gsS@5!Zv&8DcLAZOC8;~0^(DQp5GkAm$`0@Kdq=0M;|E`BJMYyYmo)csj# z1PE!PVz~}VL5Eu)REe95LqHJtAM+yt)&hvZatIoTn+ZVeEW1~FeadS-QBeT5QD+?WCbG=lbwTOdq80!7pOap1Bn0`nTw0Y7$ZPuz#2TZ zh2#1^|m17hCXmao;0h1#Y_A832 z8J}t@Z000@sqyTSpd%A7z9BZr!cgc3j$|Q{WqZ5Vn|X=Ap*YzCHEvRKpBFV8gB}#_ z+JE-L-T>^!b1Q&sKnrQN?$|-f`H~2CcXuC4NZf#Y$+p{eKuJEwpa*k zu{PM^aFDP&wFCT^-)bxL_st0s20nc7>{x_T={D$x@RtI-Gfuh(R+8Ul*4xKi5(b0n zi#m&TuPo+{>IqOEt8a@7nayE{ouYuk&0`C8u*LDXzR$o8y0o!F1uu&X1&Lb=AaMcW zjfPFkU(TC8h&Vg=Rpo3AIe)Yi7|<@lnJmNr<|z&4Nq7MoG)_;4efV$(67OST4FFQhxn0@;|t2 zj+e-l-6lP0D`GXT74z`$z$Yii_P$uu3<4YuJRV>kBmFkO(0_3~xJVsdt%H-=rWO`A z^*#FE_1mQqicoF){hRN>Xx?Ui1bxA@tDJg%4Sm7=$Jkc7gSUk-_T>xBv(JJFUaP^kU}#O-7|6y&uYl_##k!u_j|Zp%NG_BYD) z)Sooz*%-7_GJ&T&1HWp&ev2gy=;qPQ+?X>H#J2C;%0m>m^@z}Ep5>qzc&Uk|S)QGr z+x0=;B4_)1aavS_$H&JNH8gHPKm$8(e}Dg)tmT-T%PY_ht+5Y&We=$bJ!e3)ja_4F za@+g=xmIsL!~)_C?x*c%RliXnMLoTp*>QlD-UkdN1_+G=5E?MvMnIy+ zB_`x&nYA8bqV7`bZx;3HUMX$s073-@=q?ocI#J!i=NA~s3RFP`_H3UQx1`vE!Kwvxv0)y{ZJ=bh~@H-V+S*(4+p-qoTRuo~1r@wPpWDoq-d#MV@;p?MR(}idy+IJDJ@XIvxbVys3N;jU z2K%(g2Hq$J-ne#BcU{x4f~-LQ+=2!w0t9;a*`%GQsOUY=XWe|W5Aiqs^LI*QcnU&;zA~nub9=edR(x8vIOTu)#{akx zoVH*K5>q_@KrvckP7)Lxi~{jN$B|G{B0yYT_OPvNQc&XcxBWBTjJ?@KbUXLj+S*$< zIF1fHnW+C5jQ{cG|2>I6H*6h*K?!p|P&``KnSz+u4=9TFzP_3&y<-A`RO#XWnBuYv zbH6FU{~XDAe}5{XfK$Pukq?QCjMOMLB~X6xg41U9ac~!SAkrXl@-dRH{`HaASX#yU z_Y06OB5nG^fB$-pj{A?61B&jSPm1kt4fFR;Bd?gDAAjrCfA%^6wB-fAYL)k2sE7ZY z`9I*$e|@lCI#tW7Zxk{90nYvrtbZAk|HF-_R-cdL?OQ-9L%F#J{}27~ zKMdkO-w%+Ne~H(BEf~z0Aou@X?S)13f0pmhf9{a|QTl(cBIY^>&7FeICpNS7DA`dU z)NiMT6kmVeM_$)Jnj=LFyIvRwC4&A85)w9B<2=8&SU~9i+@?D+!1PRVTYt#S%ezkH zzMA6C0^DTSB9`#@#KZ)p4(7i{bK`h>DtL5M1LB>WObycd{6Xibn`mg7NY-puJ+yN` z3!wP%|FMs`#Njb9#0XGd937IW!n6rMh(6H^i&#tmMvo#Q&r56NO#xfJSglfrJdVV=%F? zn}FoA9CihHU++Px#Yw(X=Owb$sHG)qYbZGeJ3D)o&dB)b6%tzh7ruD%8+}D0$1~K1 zwk0m0i}5T7WAnP%$ynOU|2~YRXe8Y+VJ?#g;sx+Lt zkYoX4Y%4Jz$v6E4O%y`cvERj;h1|_g z0L=(UM7v;yj&Rw|!zh5noLE72g#}p+_kR5N;gm~6Fh+JDP*DXA{F1ZR9DZn6sX#6g zXq&}fi3Q%AN=8n;2So5x&dBCu#lRCJOahhTNG6Od(uYee3JMDg@BWgeCiS@T!4sWr zMu(ELcs$?k20%LSMtENOO(;i9T!8dfqUb816TiwQphFm0SzAD^gnaFCI2>_534Z08 zqgO|TESxMKlLt;mv69;Z`n-vOp>;`SficnGbg$JZpK|z(w45CF`O$_y*zm=bl?Cvt zJg&Nsa@PZTko0f^;<8m@Tz&qgFm>ce8xA>gs*GVR_^o#vodSHf@a0anOwG)s>bw-b zWMmBOdt7yyxE#e^zv}5E`?`)%JXzXTViCB7j}6o->XzwQEzu>ETC(dT=0v^A>x}Gb zD>mW;JO0tAK!&P77J*X&6a z%BYveisFOHC4?cRlH9q|VZ%FGyBfw~#a=TX_nJp`*Rzj1R$yU`z;C!~vrKMb_pcdS z_{(PW|F|8MkYK)F{Sq+dd#AR1U+iy;UX);OHIrqR0tM_-Q6R3aoz`TlO9x{wES347 zPytnHg>F}u8<4Jx?C(V+Il;d9?Y zITj(oSa@|GXIWkRowE8@M^LEAdhMlHqF^C4WOwj|0x1h{<4)kCb$TzXoIcC}Hz#pX zU<|Pb0|q4?P%y^c%v1VCLZi6mdOlnF;M!EYwK`Q*W(9w?b^DDGQnG=)fkf0k0P$E@ z*aJQJj!h4$Hr9s$?Ou!7EpZciW_93Jn0=aSHO$oULWWoUJ?`4lEyU)o<0I@+Db=9r|tL7!}{PvR*dccKkTIGrdmZnAf zuD|#DUC+i77+sl7=_}=Efy-zQxHZ%+v0nsu96*YPurXh+eT%n4^}=u5G6ojc;8^@q ztmROKERNT>V0kgX@|LM}ggk0nxQMA@WM@T(2!lQc=v`C5l5J^; zx5H~8XJfeWI?SKhP`KHUiRy(RE2%;vYIM-qmeolQxU0hOn0|L$pSm#e( zBl@ntl%!3jfAZ@JtpBty7X(bOxS%#vBZfw}cf~>=Sde+JAYav(QGn@j>o03=9Y}!Q zY1~%H958Of5}!T%Y)aXMz0-woREX2gbZBX5sZ}4)18h?}*u*w=J{ce&w*VII_CGo& zs(E3r%?JXkpE=$55RP%WZv8q_ zkJ3K*K%_{M+Q=KJGygV%njb{Buwfa3cMM7^qdsEe;rZv~<-M5EAFw+n_k}Fbz7zuM zFy7!2Foc`2r%`T03rgX>2ki4DJ^d!|R7_*J#x+NO{c0j06RbBD`R;yob%|oLW~{_7 zNad@*`nZu8TX&TxVD<}2fG!u|_l`#dVg+K=EI(jPqI5@E{=!qJX%Vg_l>OU9hwsq` zw7DW2w5rXYTXl&L1?HRVe1XlJvBh|?w5BMv$c+>qjPcYgtA?36v7dGm z1|#eq25fispT%yZTGPD4xD9jgU{R(HmO?ap#jJ$4*2uW+Iu{}c-gXy?L0Oyo32&Tk zL-$K}V8d`~@ip}l(_ztRF?<5N=i=){a*@1`%H=*&0`vVF9ToP%SN#D!XXf?1Cm~_2 z^$jV!-?N2QcXq-jSi^GB%zz0lt+!jxOuQ7Xe^~qNi~^ajdwPCO#*+1UlH(2HuFILj zi(F0&YvH(el9d>S5o&5dQX(DHp+x-Wu_dQ@J-+1{I^SHoA3@$m4sckHy%a8G#Cq#l zRone*kH+)QPRdS7Y+hye?=_pg_p8(sW%uZ8YP3z(zlq^X!gY zGV8I>i%BYJyZo)$R`@=7%y-y-mkhfnn5#$J) z&TV9~(U@put7b1|Sxr|5l0JI%1svbtcUX;hF|Cj4z0ekJ1d?KZYq)%%Q1rLrMBD*A zS8d09r~+ynms<2TM58=nW}nWkeEH>|_9d3@#*j>W@$G2>O~&s zGD{>LERjW?OkOY+?`sCi%xsP=q$r!!QX6t5_kozX)tVLSn=JNJ#TtUA!Cp6a{Q15# zHwrxCnGoBE5@U*}X=_CM8uxDGOMWZuK=xt!p+umEAu42WBsDeXR(7ly&dyV7ns4KU zT@n1R`U3p2!V9n7tXr@d$S>MBoBuq%q(njoISq!u-Q)K{@I&+w#oJv&R((NP+q&cR(10x9ZF!oZJEwz;yw~kdPi`=^yn~Dw*$u z46T4Rh!F3|$w{_8lDl`m)YMQyfa6T}afBW!mx=G8_hl_vUv(rlX~M5O|3qn2f1AfV zGQmE#E6rqQt8jhgFvuD1ll}vNg&Xw##PI8Awh>v zy;B<}a-Yn*f4Rux?_7Yjt2eSNvHA3cIP5q5ZYErjrq}8A0#pMhsUSTab}~&VR8nQf z!@sMk87s}qYcg-gmmyz~ljKKzDU9d#V&mL-P^(s1(j3h$)_-n9%a!k4d;GcE1&y0u zKT^@xV>g_jC0t={zp^Z`Ck?>XGHWPTz_GKhJgzd?F?o4*WkI>0BqxFUns*gQU7K2| z<+h&8H7{(+0Wvm&rG4uN`>w2LJF}wKeXT9QB%jaGwE#*BymuuXogQF6{U-Taqqtjz zAAq&e^y$&-!=!=UT3oF4@Ib;HK36tqVg0HJV@)C2&{walgP&KPRK3KafuoSIjSW%h zPV36&Dje%wI_>KJsGic-&p2O3f5 zyHB-0dBP@bHm0X!xxO;`yjX8CuqYuGT3WYxbR;F?I?|oebC67%R=sc%rzt}EJG_4o~k5x*1?|E_Z$gl{>*2;Czd@Q}>In13Pn?#H2p${xoN4!-7 zz9dF-3oqoe=}9F)g>R(!UR&WC#L!@00XJ(^kl`i zA3VyFggr4+*WeOOy7xX1Xd_NHR@pq2wDCa&N5b(s>&CIhSfS91%*cK6M?zifk4zRs zI|^-+Z)b;IKpyube~c(D8FLWlYwWspS#MuGkOe=H^Y{a2X0Dn4~REn1o>L?KdofgV>bvbsoB| z>3K);{RpF0maF~5KBb{O_uau3jT&hFLMECf`Ekl?cnojqCSTp-MeJA4%V|=nG>c_k zMmFe+CY!s#744Lgm|)%7Ve>xLP)**36srTL#W+r-FNh-OLpV(2?U0=DnbCpn(pj1< zyIP&AlJmWYQ~In@7HP!p^XzAbIIztk>r}%5meqb;Pl92qvSVIZV})SjiG_RXd0%^U zEKb}Al+<58r$B+gq@|m>vJLotkYRGB z;;Idp?^&wCgmXvr33KgyLVIxMqUpufz}dGpZ$l8gJg|U<>p(-b~d$mvF8#$VwS=+ z@8k1WCq;=Jd!Rd(6u#ggp^n(P79!QmllLo7$U`a8dpxYYR&HS)Xq6w6sIWTw_8zqW zh4&oNB*Yic)iP)9{XF;#6gD&RYp?^JHoqP0h1FrYRcA?ze)vnFk_K$No}k76*Y7`{ zhc_iXyZf-4I(YW~rMU`?(byYP;w4N;L}LI| z(oaVqyIz<}9W2S_XnWnBBbD!0BbGd;wJ-Q4X}&D0y@XB<+>XB)K;-ji{+l5t7VS(; z+1%pdyC6;kBJ(3m(ci47t)X}PM{)uKqAAsNR8LulQB4##uBejyPQOFwpG#)tx(oW} z{21xUerC@qJMD=>>!Y^7x>e}EE4A5bBE!4$3^s_0P4b5RzEeWqh0FSJ1;fcQ(IZVU zxC*nj;lU_v=FS_uulGf<>PJashS*rcu#A^R94`8MI~6EC;=XEw7SzoZk}=US^nSqY zyZ*?RnV9Hg9<+VV44jE6(P`KsKhcu^uicvY{!pDOndWpx zh|xz5g;=r9{6~6YQ6=M^g_u~LF9^&HBRlFZ8q@F*vpW z;Pq}i(Tv%o^xU(2R97Hdn!{|9>A+f(7M31cWZ9fq6Xu^|_v|Ra8S5+k-5dmC4MD01 zYo-8@m~h*hw3z<01lebph&9ZdhZQMWL1{KW4z)WQa$iR#iM_kMB`7naBQ?CycG$ad z+0032Q5mqm^U`vFLW-LZXBgq{HFYDFy6uf-0*;_d;R4SLjr6fiuXTpKl+_xdW0pxd zR$bCl(~Zth_f{5PxK#C;JKOQl@cSU2*9C4-HamQMT^k~o>zLjgnLO44vL3;w}+#%PG{|ltjJU?PjTjT5fWvC zEbkZ$b;hI_yBB&XliYLblqe z??)7>2x_&&K+(?9&~{0KW+NWoJi)+U#csm>+;td3?cp0F$94yg#83@R^iA{W*QzTf zw^ob8qvHZEw5ey8tZXUFcV36IePT~ffQAe22Q=7W;K?qvK3~($C3WX}{dD3v-B^?CMTT`*<{rSjZZmRndH@qtfICk6{8&*dOwBP@g3&_bp^(MdmubQjbr|*T& zc+|G6e+gM1II}W#SA?xHgwxJh4-JpCHB+z-wVw}hy0GW9YDph$s5w`Vl8TrX8A^Ia zR+-%Ct-TjEJN-3y;sr8~z-9j?6t0Es`0bj|w9-HRK;DHp?ao_F>HNy>tEZ)ZT;`4a z@<&tpMaw)CQ@{gFPMc_OS+#cn4x49~m4Awh10OQBuaFc1BA}3X(&5*=iN9*R<|Nn* zEOBPw*T3C=HiB?_Jx7-7Z*v*Ow#9zR#ydZ$G9yY2Q@6hdz&~S7C0G15TpmPY!4TBI zAnr7mNnX!BRb?Z zIu2kMG+B`*;KU|!QV}t5Q=Wq^(j5Br5TB*aPVOZM|Io*E-p`lF4ir2yy9 zf4(<1E1Vj-y~+Ja3{v-W?X*J(t(_^mCFz7vK1QrUVf-fM{WQ+%`zr!Q!rG+2Nt)Ac z()bjQgBvKsX`_|Sy}Ck4V2l8PLCv22BjS8204^UBdSR@=yZu5vAj(%W6BPn8m>PC~ zmH#rliB|bd#inF)FWql)RGHwS&R1 zxEQ*yR1`2_&~}Of@@=I|O*5yBdYycFUXI|WP=@%!-UGbi4gqlNWniY#&U+l(1>zeZ z`F7y5g3tsRgqU@H5#4-s;9EEnBg(}O-&a`7X3pfW?AO1a!ShCR+E-%h?Fa>3XDkjy z4P>p-J(;zAJYV6g*+M}NCURh(SYCjJR!8Owd32rc=<8B`=Xbu?LO~n1^&;C@;z#nF zMxtrzr3$I@GozffzAWJ8ecYFxag|A=bGKVGk_qppDyA_%&`t0t_+}Gsap<^s8Q^W+ z+!P%*r3cC;Db(7-c^r?S*~48rdzZAtKxB+9#9M!R{>jke+2ae=VWowtnCz*fz_f9n z+V63>v0`epPh-X6BkKgDU(PjPksYVc_SDIcnj!Y@P8nmp4)JFO3ABb*!iH2lzviRb(f1{CpRD@DMjvXo5 zm_x`fvK5OOS}?!p_cBxO3SFR(eOkI3TioQA!=P2L_)+P-ViKuT{)z>3M9a&ZwO7nR z+a>cq@@yaok`1=$=Hb1nxi<~LGfezG~Wj3Rf0 zjW~LVpNS95a37g71+|Xx)ZW^_nKis`cl*aBw`z<8JxqJEkk8_wKT6SMzsr zSab%qj+6Q{Ylo$;-}qWHO~40HbcH(h+~OvZA1V3%ossPI%&Pyrsp=4S#xec8Q!@|= z-gtoWy1L<2sChs?5H6BYfL_Q_i+%Qf;sbbb!QhP{DvhPQ?Mg4@;-V>UDw&ulMM{ca zU5a?;*+s(Sv-r*Su?3|vdrHHZNcl?2n%irBWer<4lw;(5Yhl$%p8_>%p5A&ZBTMyw za(fi*NY&&B)7^{mxkaK6;{bfYv1@E$?hO)vBgfkszUy`-Y{xHwkx=*Lq2to#PIx68 zfm=X5D1#TG9d`KCugiRp#yy*xveDekVg#`lXJN1_k}UqiMo7PfZOO1?v#ZR&o`Lpu zFEyUJkrRBVfXBDGj*Lox3YceP?xYU~XJ%%8snU?X4sJWjjM45>DsNTpu=ZhF zD@TWcPbI}TyO_e~jTu(!2EclR4>dv@${7fyM0%*5Hx%t4vc3uV98>iu1;@LN9jo-&<8zlY@)^SaJd#qG)KY1s4Rfn4 zHk5q4iLX-4d4piO@VcX>hJZkbDw-UX;K8U9L8)qRPRPr(1S~JzcErF*NS#Y!w;U3k<|4;TI1^7+c(s=qnE-7G)}}ntRZY`Z)vWS zU^K|+jXU}u%svS3*q27*DrFiI&`BBYYCk=DGWLe>V}a9>;>PD>idVgogkRRvX7m7_ z4CPD|az&ns>A;Z=lUaHq<;di$8|tBRbxX3p|DFSJxiL|?l0Vm?Rf!G8=?nASGy|$Q zAufCc_LqT^M*Xnbl<#P#d1B2?eT9z*BQXi7;sH?p`8NprOIzJ1i+w+0PlfIV$x^#$ znY6*wu>;zI=o?^v-0O$;m(1Yk7RVk~)Z8W|CpxYod4!)ZSwIha%w;Dg^L|aq?8G=j zM=(C(qqEk_m-kulE4ps8j;(`~zY|H%MLD{yy4PQxo#eTnIj0d=GfJN0NFK+#Ena4& zQK^=F5yi`)G;4j(t+F@9y1Kk_dL+3m*L3?@8ao)a{X!c5$~Jq8iSEO}jQ*D98pl-y zMg;Mz#kvV^8{;|vwUJnv3x15(($MOEKPg>{i)wjn&~_D~3ZM4h z=Zm4uN=Sv#(Niba1_YCbPgT|Z6e;Bh`$(?ce-?U+y7X5gi9ghGV<%E{(xId9M}_iL zxiztJC3)BW=dh>>@S@svRV_Kit42HK#c=ef98a`tg{R@Lnh$=)Y@@SxJV1F(E4RB& zJ3?RGE#6RA`{9pGo(;LUjlPkRx;R|($z*J*IRgb+P#{T3o*W4AOFJU1M_&>QZS=Sd zt9qyd13qI@0MnL7tH^fGw}itz`rtZS!qPeXB(!mt8iHf#olL%ksbH+&S>uV%BZAv@ zyfrM++JW=gqk?RXs`Gp*w=qIZIn`#8K@zAC3;jukf`M`c-p&~fbA-LSIT}|??h^rU zex@VYm^SGV`R&5~PMi@XI~Bno9ggPa%@{8kgpycXN!*ikF||Dq-bU0mu$``xfzjjy*`U) zn?A2=zbY#Bv23=t|9RwI7Jop`7Rg$mUWB?{Get}Xeaosrv-Jpnb;tkd0+o%vr3?!b z?7`QR!>&5oM^74@HMA6*aJpx)xYmmjI>VOYMJgVr=FOHdwVvbvCXrR1 zvOd#N|2h?a1A;)H?$z^uyhz87q?D4DP6M@;(33}UCpioqxP?VbmR`y!7OIYSc&-+z zIMgkNk$h#KllAB0%5QszP&#l#ns|N;Q573t1`g!?Sn8cZ{z!*PZVt$?@!hV)TJ>#+O#|ejT>S zLCzoZD~+~2>VqsYN$g(va1MW(v^m3-b=11$0(Gi>cWL+pou(tiF$ntgwh9L+^d{!V z40_eX*dO!;mX>8U^QjJT98LjiBQ6-w;mwDUy{p8}6Qh505)4r5ki1%ZPGiW>PM@z` z4Lt1*E;(D<0y)qz3ABMh#&e(iiK513Y@LqvdHEe}j4&sSa)2i002f}RBIkVPzCbYM zj|DJMr%OyV$A_e)VCy{G$m47KngSJwY3OC<9ync7YF3JgKB2Yzo)WzY$$Nk)GZ2bV zN@Lz6I&nEA0pq3Bb2V$`09k4o5;ijWBgx`Zi{Z`OcXv9Z23kJz?@dFSZ!5Y4dP=od zW{U(o9)~t1JJ!sT(Ei9f2Dn+m$uSL_`^zStS%8N$Z#mB~1LI|rF&litaB*V!J+6K5 z+owq-P2C zKMnI8PTnPpz7-)c-x~o)<&g&AabjNUj$V-Tm(s`Pq@`?OQrqgUlHvmHMp`rT7~VW^ zRoA^$%U-^rU^C*yXQ4?Sq%e}Yc0r$bO4k!&OI>0y$$)MqhjUV;E7xzlAllPD9$|E9 zf6<^CcbpJbm4af%IC(ETw}f7RS>DPta_arI&n>Bm{Ugb!jvhHWB?F(k(b!as=KZ0> zD$I57U2Dy@HK=Yvgb7mgtx!1>=juX>%*Azl9PZjCzq771>+x2H+16kE9>DBf>5r_hvW1ieh4LaX@54Q!V z0L7mf^}SZq;@%zd{xH(dv4wip?6<^UC4xzytvtD;of#!+%spe~pf4XV+1_4qYNT26 z3hIqmL2eHJ+bHRb1WZDP=iDyw`*v%%&8S9;OYsHH?qLr1qTl(4EQf16(}Py2mI4cE zc{#lIEXA6mRZPoUUZ~%M`AL+~f{=hIgg|p*s1v(#hMfFUU)8-D;tcgHrKz)Tm6%(6 z&-Dke*8CiXVpL^ZIY+wtwtCvnG=_Jc%X4yW69zXE6?!>KzdBhE#qrgs;J}V|w1(!F zvJi42gsnbAmuCDF%ZLr!BIQO9q*~P8fGEJ2;)Nmaafa#ytir9Y67CyE;9Pb14g>^s z^(zJFjaYNv8=Sbh76s{jjUWj~K8ElN9jIY4&@T{~Me~WJ?+^HlOmPTyYG>dDXu&+l zm8o1|V#@tedllAUj~|JHh9kW$4R0JP%aH$N?o=1v9!HsJ%Cj$65$~zE6G2IR1;4eY z0l~X3W()rSS6`>#;?*s9Vjj@`+-X}l^`d5eo@kJdBf07`%KeD*?PS|yskH=qo{Qo8 zT%78zSLI4Kj;O|LU5O?9dVKvOlgsPc50FMrC%S%=Y0d4U!f!{VsgDO0Yt8BF+WI$~3N1S{umK1b7HKC>~CKzoWEZy%K~b zMSGN1#DC!wwVe__#Y{l@(V(?l!RecAvg)n9U2o(##nw)$NXdmxsvH?T*wEI)C_PiJ zB7$S3HGhioEpj`LN6W`S;uFR*d{B}&cny9L-0(QB#A8iOrajzAkS#1_j$b zvFzO5isQ4US}?c?5HSuazrcIpy@cfGcvLwj@!+`N;tDnAp&i%24=qH~bGlw4JR+#B z8#!8+F>{z_N^3DS9OXe(>#)T&#RHKX@u4cT{KnxmbOCi?ZE64y$j#IC%>Zbv{kn>E zreV9KVw#!>CVb+4m#*_zN2G*cKvy`61%CJLkucn&{Dte)={BQUj~6;Kp3Ka5oVW|> zOx{96AN!W3Bh5j*j`MF|I8m2Vr!ySs+Lu4HkogPzFNAxelOd45PA}GhpneCAsMjSY z-7_Y2tuL(|RKqFDO)S}-oS=Dlmc^0ZokWD*N|3)0$gDSfD!h26^$3aNQ?bLURo=Zb zDcqZ3S2G$9$F|iJ7k*Qk{exrs8aK`B*Rr%RlAOYJEBvIk2woF zf|K zUdy(Gz`IaHhN(72{{5{Nw2kYI8=W9u9CWt_fHDi;=rh}|z`LI^626D$y~hD-{(~Gk zZAX3mMNdbk4~ox@)?Dz9k8h`xp_aa~;{nw@ICTOxTOTeEa1g8~3NVITYoCNp?2~xm z9ev=7cw@@m!hS-#^1&evF{2exqd0d&c1)Wx12Q`xFC$6}sE2#vG1&>(i{8IzZSn>A zo}7GCLe8>;gpOw(Gn~uz%(k5;($^h|bz*qFUBT&yy>TJMK2P%Reld4N^xjd7)mC+A z!ljNad`HYDgWqGo8J5C(+zZ%V#WWz4)N4r#g3BbvE2i)Yc5B`Q$~lTI zvf&iNm$_ScVOtZS?v|FTLt1lO6~_3;G|w29Nwdth=sfO^X`z-+k*7B8SGbp;i(1Nw zeXY8hS8>s*q1TFuVs^WoJ`aC-d@y@*wM-#Q`0=*ci#4oGogy+gv*=svy6gr#z3kSV z*m$Z~aZA=WLL!SSdp0B>m7_bfZ4U0hmsAdp+*+>ocvvNQyJXrcE8WW*_Ouea>^x9p zpRqQcWT*nJK?&)CsDR9BZ2w+G4H9X}w^FlfTXAB4KS^>MttO|nhiuT)xpMdRW1IZL zHL+%5)Tg+2?%p*96mzvs)sMGV=|1vevtGQl!u!)?&pz!*o$q`npO!eCjX(#DT1fr!0iBLi+ zsxWW@#?f{1lT|+Hg2k4;aHSz27S`4@W`YF+Qve0YTOm(9Bzf#Vg*^7Wq}-f=H`t`! z{yP_7+*qWY8-9KD6+3c@-(0wQ`C6z@y}k5XJ!X!FRdT~pOBe69w^eWH$c^+~z6C?C zfrvs4r)s1jgA=n&@H*5#8<|9ACG504nA86ywvT*U|2p!8T3&*X-SCP3NH@1Jd!(hp z+XaoYPTi(6BlFxSv2!+w^=FURmW3!E+MBewi~5ZJl#tY0a*7|t4=L`s&H#g+t=_Xy zeRZPVqI2=TD0}O$D7&_ObPxnVT2e|vL1~aqVJJ~TKu}6rx}-}*x>KYy+0{zj175J^1qK>aS&DI^tDj z$v=AuP(7Y&W$N!Bf3g^|HQL58M?d3SX6Vd=qwmN0s?}eI`O(y01A5M}9jogVBNDs&tf+sAPM7O{ES za|?|U!8Z2T zJhM$Hto;yBIj}axpy}Xq(U_K|3rY@; z&t)X0gDo<6%A%iK4ZLgIDW@3%o~V|zR?5PGp;;cAT5M$Tw6h=k^KZUGl%oK|CGZoo z-{#fW2RgT5lg+99axPlCJ&940Sn@$D^lZ|g!5iWLQXqdIK&{5atMdfEoUx&di*}EK z_VlU%-jIfXH3_Qe%xjFF9# zFhC#v8~8-=kq0OBCkE0VvN1ml7%rBCHOjMikOVB;h@V{&5AT(Xy$q{mxT-Dwr~Xby zv-8_=3K>KTN81+dZY3c4(~^E$k-U(Q1oHay0V~2n`t^NJ(1N}?dzFR1((K~#y%_rt zIUCBXF$xN^;Smq+Wb(VBC~8JrPx!^&yJdUGl_jrVd}w99LglOEr`-O_JU1^<&8IxD z%2R)CYWpkfGX1^mDQ7qFP)S#qff0e319h5cS~?odYaUP@&Gm35XOu1Y{ekkT;+ZnJ zpqH_H=dzEMv>c9jAaVtUO%$2gUl`I~G<|T)BoGYA_5^Y;P9=teE=}L>L%!zZ?C^Tb zOPUTn3X`}OeM_*j3M1P_z>oU7C_lfNx1S2?U2Kz1&}s4#?4Uk{i*8lHZC5FZ76qaD z#I^Ru_SyT~N!r;>@Yn0M4#Y(aSUal=YWb{U-L=P-M&(Zm7el}BGN5NiFja+aIHqNE zA9u{rtacG0=T0Shjg=(4OVx6^&l(chUetMNtQxUZ(3n&G&MP-+g952$!M`w8y7q|vf2 zmw9yP?HPBsKJ1llB9_!ypu2rxLGJ8dggU^@02^yH+Ui|V!Hpopd^L7 zR5je_|NX2`0($n6WJ^7I%WWsiqQzsGdGFdgH;LBP=R{+YlN0ZL5A^B4x0fiB-}A7p z2F=n0@%SXwXM}d=-N?U&x!#7fU}uy0(UENJ0Kx2#zJsOwLVoO=fY53wXBIQ#yfyer zu@fl5!RCXntx11KMyiowe0_P zy%Q^*#M~6;S8^0_j9JGqLS`%Fy(q;_eKDkl!xT>tl=uB{c5l(k>s!_>5|eS8J*a+f zeFZo9jFE|87+?_UNH3IB0RJe*Y*uOxtk`t472)g>MEpM;3Xn>aMWAE}+4Q;K`mGo{ zYy9jY-zBTs8pm!LlP`@5W7HFGVeQo0>nV22)J9zz*;>K?It00{XkSEX2HsxP%#G|T zL+SlCB!)kUCp_s`>W3>nw4?e(|NN_7ov?7XE`xBcIXH5Mesug(vEjJ*(~kBasq@U%%d4KX1Aw2wcWMIUza&Ug14qgtsM zS`K7%cM{E5`0f+k-A<#Ld%}=yDEG&|zK0^hU&M<&cK)x_x=ziFGu*KIauib`0$3UC0Nm%IKibpjF4M65=KeTS z&nC%vS2QSUi61wfB`;7UAna>I(uB*OZlDjDOr`r?PHd#&DwJ>FA>QpUCz5!5Xd)0J z=+na!`7<5yHbY(YsL3hw|_()(0s>WSQj;~Oiqt^9=iOL@%{)(aU{R_ zQcQXAWz@Kwj)PK9efccmcz<#~`|})p61u>f$m@GAa~SmOllwQbn8T446lj0)@jpA_PmU>5Fqh6GsE1C=AYD z(nX-7q^HpYH5-p$T-sSQBR?9#hArml(P1Jp0g*U#6LYVuHRI3Gq1UD6g|)d86^;Ah zDH?#L{n5;Jo1;}q11h=myQ*>C=fu9vpN|oSmymhMcd=Egz){(#;v(Iz1E7kC236Lp zop`nNP487yya01>8I&#+UPRebNI5$4y5GW$u0dxvdkQod^?UMOA2n;-Bv&z zsook8B41@I>w?-WP`@;ao4|PZkSkXtEt8&_#Ugwj7N<=GIlJ>wu;W@Zzu}j8_(>Qj z2l#ryaRY4EXc-ugUauM4tiYuTsrSRWqBnCa_Upg3FXVY>appG6-#bWTso0mCU;;gMUkFY7JNx>A>^6&V;I zBDcJtNr6XK1q^^cR8$Blecj1r->uE~^-><|Ja88VB4Y3u2M^pA{bU?TF~L>5J0Tmv zsWml^=Yx;XYQ%x2>EQKDwB9#BbK8}bmVPkr3VU1I&_qN*fn{lF3HlPuxRGmVX^8ev^Y+nX$M<>tM2fP zE(VZXsDRuieTZ#TJeQbe|4oVSRz!q zctTVL^dTwW3?T?vyeWIYY7$q8%9-o5KHh`UI}68S!KjJEkF9Te(Us$Qz6gh{IH?}O zsG~s>hHdkfWmFqy@T(s@crZ94w@PN#9xr~vi%_yp=qbteqeO%0T=2!} z{O73d;RPIs(@+z67O3Wf;PJ9h70rGFw1qE)^Ka^d*8(=-4E+OR*W{$6&u3V8RA*RD zgyHr;-h!&%8@x&lSFn^pA_0TrX&AimY-K~7X*-odQ*BmMj+KGo0Z?cdosv8uGYhu) z%_bl~MomrK>q82DI2#pB`;r;_Vm;0h0{JVV&z?|ouQnrt5=dfB%n)zKS2|GL1a+GH z&k-2SWh8x>I5Dnw(4@D%lN_-Gz70%v%o?ro0!qEk)0~D1)DG-@E^V}gH&iS-%mhO) z>oQT5GOHQ$N}bKYl#;#CHZ0*Aix!Gk|7#dhv^2Yl;H{5$=X#E2m1o1nm@X^QAmAL* zehSTgvW+D33T&y{_(UGqf)DP!lW3nly&pitELLfeqg@HOnbb4(fG=fbXLo<_EG`AX zSajjyI_(@_Mf%k0nAnpK7<-o{COcssYAQ_To2Mp?tKePwq|D6BydOi+L{H%(V=S!l zV-~%1aC_+L1}n&gIC%wf5Ee~I{P2Kiu@H~;%49* zQss-uNyYUaYXP1k3kGOsYc_1zc+bE0EsD$1GBQm-Lc-Sxw!YNE+K4g;zjZW8OiToP z_dkH08<3ZWEG;KD=ztt=`&bc7VbQ)*T@n1QpfC zSr+4WyY1S2h5=QzI!h?@9kA$u)moYgiDGR|>1|h%tGyWZZded-?Z>L?*Cw=cr|oR* z+Nz${R5sDkbfnLRH&?-1l@wlp3u#-l)Q#mCn#l8Di~l2(xgLjEw$`5L&JRO>etx#x z^UENzj-ha>xg)Ld7ISMXJWKdneXlEY2MoVipr^IkGWkFE!T3I9MN9CFq>k{XvJlA7 z(2x~abMSe$d@MzFD?? zeU+i5>MDT-yQeQaCf>L9YnvSjfX$2ii6_k{aMbGhVOpuU}s(?DV_4S3dz5!uz6;Qm8hJf`a_4ch03ryiC^E|J+OY{dUtqhUgn)M~B)X#x64>@-l>ID~JFw z3lsA4XdusmH^Rw+z!l5@gBZCJbs~v@_iN$|3n6uLviS``gp4#l-^$FfpPO@eViS$H zLS|rkyor;a&4s5DhSBO-BlFb*>WnVP3}b`-*7GZ1YxDPn<1%8ei|6rDe*#H4A!VBP;xJV;`$QI@|7?W_3#kd8Y`A&yl_hW^U$!-3=|6Te zVIo&Ug+2QD1mhO|q<&TGwh3b2fc8qcnPb^o&OCtl1_X!$L05irRV5|QATpJ`jD7&0 zF6^I~dV~jC>IL>~vs+5hLUsL7Tv$ZQ(X86owd;fQ%oEtOfMt@jpDQWplgy?73i+ljL55;*}}_te?e^?T6uPrJsvCGiX4{ zro>LQW_2`MmV_;ts;=H;vW8Lf-zyoN~EVB1Gz1xK|wslCS!&WO_BjAthSS` zOAnl_oTNzN6cQ`4OUD}ZYmMkHubuE3gxv-gDl7AAho5Ff60xF4Pk-wEV)f(v-< zdPMB#FF`c=?9+=MA))%`E7IXv#lZj?B%aR}Rom?}s-K(5;z{Pl($Y6F9*fBu zG9Z$W3|zQF&^T#+@eH(c9l3f)jxdVE9kw(eYS6;-GXhqVfr)ANqTuv3um*`)Pz1D%`yA(7IF3EB|+WnxxWlY$d{ zDGZvBvy=nv4;p4*BEWI~d$St?y4r_89V9g+1qp}{Ay{hsbI5ap_P{)jM#tp~{7-=w z{SY7n0JLSbKLP#O&c43;e=ClF$ZMul^y#wzIDB}=^8XSfc?1Zz=wLS<7R1KHgaQGA zd&tOdO%S&C7?>aM@ZX#MchG$04=5-B>P81}pTj~!zq;RC{+dO|_^eg~0gbZBnn(YA z_kSO4YNl$Cp%wOLyC2MED*DFflHUWD<6p1j-$_lh{?`}ze|v!>7Kex@bR;)7w*_=P zHk-pTY5VI#B87QuOE#6Yaqc>VT1qsk|HjW7%;Q{9qa!*q6fA86~p@PH3W}zFaP(f_9LOdzay*rS$H;YkeDXL$;pZO$&)|-CsU#=3oN6hIsB9^~Tc%E5W1 zW6*wlu@hb-_3zALe@Vpx+(YK~n+QMX-y7+to@i#r<1TtdRn<(VeUaN0ks{-fXA#rj z9enrx_Z3Fh1<6b>vq8-sWCFUnx_pCzypocVWcI+5=dbad6@hA z`(WXF;j`?=YJSViB<0CO~W!R|ky?Z_;@qw>Ffc%fTM@e$RVBG!qDMtVk#Lz10Eri%ZD(s6>7g13 z6deBk1>>W2*cS74H!^|)O8I$C09EvV{;?wmoM<2ch73XU`KkD%13zAiwFjnD0xWqO zTig6mb*JEHoOWtd@UfL@HS)EEsNbzf5O6jKfik-a;QXzg0KGFH?q<1T0mR*qkB^VV z%+2!^4-nm>5W0&GPZ5_Sutw`bncCEk$^_G zAH~Pd2^`e@F8z}dM+nHpX+D(Bo#UDa?J^ZrRUga7oAIo3eFK9JSv+9+>th6OK=oN2 z>uGGrSy)&uK(KD0eYYARuQn;Vn#`LR!3jG#Y3&T71-}z$n4L7-UYdGNYc{x&K6>^B z0wEwE_yl$g=LHy$%%K3ruGxpm-50d8`e1qG?~l<}!VbbbFR>K1D?Spml~3fy;GRtt zam9e32oI3jDK?+s_I$WipjGdmno0xtbG&BlxRcN8IX_|N1{qb`(ui*5ZEgPV->?(- z=-bV?D|Vp4^h-FgQIOcO{yJ%WH&5_bslQ?X!5?ig%2}hCRgVO#YUK?5Oi_{&US#6ufoKaff*)a06NaByBpk z5`P>qV;gn))Yb}Q$R%JvI(vIZT{Ox;myaw5 z%m6=9)59z2^qOfriy}VY1tP*nu&_JVTIS}klrp`6J7~s!o$)H}$hEtwz+tcp1my_Z zTr!cnZxM6(ryk*01jXTxoMQ9;`j4+iPEFd7Q9R zLjp6Om@qjyI7+o^m7POJJx|?(0{tzRmyL`c=WSk^RZi)nI|c zGfBQCiHO#EU1N^OdqGymg#2<+mi+Sg2yCSHAl*GZM=K#B+d{(0nqn+Zl3AOZQOQmy zhijZ*8TqxM`2X6Gp{S6U7%Rvhu-^ny4WONfPx?}89{d|Qf6*$WQE5}o&?vmbdhjO{ zPv^g{1&4;@6~04)0MEV^Xqgzyq-W$z&k?cV>OJeKEPX1~=|c;WBB_j2E8z3!&u(t; zaK9F@1#h%3gOD6(GmOo6xBau+aB*=5w@lA$Jl|5e0Ne%h)VyIedG11%|!$cDyqykFMkZDW5aO=AItI3*&bRgXX_UnJbhtPry{S!yZE)b(M z4g8&Vn{`?;?*rJ+oYQZk8Avlj5dN(wJ~)Bvgz2Z7Mt!kQXXI*>Z`?*!XQpE7H(G{( z6EGBovt{zSeSqFZkjINhgi1_tfojkTY`6(Ul|bd?-}PT4Ne*HkR0vQZ*FFgUxGkcV zcIEO2?BRQDtyv9N=A(}DV9HZfO)R_7(uDi}N_~;TvF`kIZXwRsEc4UE1O(#Y;gQhO z?Qv6{qq#71U7dg#=J}XMLM83ftZOP*Tx*VU{ola%?(uGe;Ep;3BpeX;Uzo8^ZLGlF z)!E-a4!_M;ue=Azki+tt~Z7q^=sG)9QnMtUI5|D7LelQ=rZXQsGbY6 z5n9a6G0*eRggcZTq540xL4t$`oyC~d0;l*1kLuX|Edz)#^%vSDV>ps{3HSHO2fFyc zPA}aYW?A&>3K65TVLO5QtQ8U==Q6`2Hci>C8=!Locry49z{v)#NbJz>gC9vrCeIx` zI}kK&C^wt)s^;NN?#GW)gFA$kX-`V(sRC|^``*3XFOjV6oSB} zcsMAIWB2)YK{NJ4vcRuj8=MDZp_glde8@v&ZybO7uoAet;hkO3(Y3x68{HH>92^s7 zBxT_|CvkV>VPzn|_#t$Ii@%aVqZ>mS9h5ii`FTNq72-QnL9un+j2br8*7`$lu13>4 zXoJ@K$tO_}Q-`o#I-{ePP)qiuAR*V3%^4gWMLcOox_gShU3Mr%8m`DR)(^O^FD&Yl zHw#54S4KiFI$L~6%vLX~_g+?*^^0vc`YTvv;A3rXTwTyy>=#QrT3{2sdAGUGIpr18 zS*&(GK!K`R=pFb#yb%d$e4i#voWE%De$Si7A_P|TD##EZ_{jtu1O2$10J7M)*u&04 zEpLj2KD34#Wb2I;bYC|*Bx=u~y5Whay3vzH0GzbL> z(BWXO{M7jG#z;56LU>O^&)!2R}tiy$Ss^^x!6{0)c2JjbfuUN&$> z!U_!c@Xo&6!(YM2W$zVi)Zy8U!MV$Nsf_ez)~w8x&>(tcniipj)6O_~tcACJFfy07 zbb<~QvB!PoaZ6}P6-vMj5#>~{PRHXT{fT#`hW9M5*7rq#{j{)Vy)z*|H$y8e=0cN_ zEGu~?fecQd;%`YXJDYfcmB3{Rey)`9`K)fo?0GfFJL>{zZ^+je68D~n&h^JH6s?yq zZG_*5@5WSblE(WB+TP;NDQEKE`rnD^ADUfAnM)aa-d1+ywnP(;Kk3l8p-q*0`wRb` zgTojx>Phg1Qq@y0r5Z&)|KpKP8TEk4Uml_ZXu^_OL8KuI%DMcvvC2@%_CI&o<_z^Z zlUFwH1(AOi-S^cjf8;dW3?vt`p~g#cbV6J>LLJwHq-%z|oKvllemYhM7L%tYvjp#< z_*1h%7%vy{&>+CO>f}bmRDc^3B;u|__@XDk`ct1+-Q%f89*!>vH!w*>Aj%d2ZB+Y| z!3Mb;WnNg@dbgpTK_1vGh^NY394EeY&Ne@j`=;(7j#$!U=_&UJiT%T1I{3OB7r%|H z!hdbJ5dkv>9PpOVph(Dc@?kVZ6d4h!e>F&4Zk6Iv`z*`Dh#2?pG zRMO0E#QPAW20#2-*eC{$J>wqdFq|e+BGuc|GvaDrn`$#4CJ4JQi64QTcT|_5U$n@o zD?E2AkvDBjXXJVrMFYzgt*a?6>$_^}Mg#RGb~-8{XJ;C-)D)N>`2Z3Q!@k1io%~SO z3k>@Av>a9q_cz>#bT4jl-zJ_T?f_~{kU4XZ4tT08EZHm36jF-&S$ZZzGSa;k{ox9?G2?me zZO{czMygF8n~>!#MYzW$fuH!QmL*h0f}%U%{L|X__7>&9m9ySSXD!p1N~RU~^5jgw!(sPHkx%)g znzyvl(SXV1YW&;2%{w;1*W*q{nFVJYw*E~TRP6E5y6WeBa~SOyL=t_X7{_VE-L~#@ zm{Ubayh;nd2p=+xXi1z9?J?yK+}MUT2x2P^Gc#K#(^%f1`D)uG+p%oF3^#Q1U2K-{ zJ;rCE(zg=U%?K3l-$&*zRGoLbv6|={BHGF2L`ZMWx@=oYjZ-TNdl$4WI6M`*GeZhJ zlcTvUKSQpnt~Rcy-|cO1%XylpSzDb9kFM#YCK=d&{%ZG0wF6i3*=xcA3VEq^f4bfA zKq?uvvsWk$u20Kgl?hH{jPD6dsBm8YiQ7@KT6nVewyB*{Jv0_KAi)5l;Ptz(gVy#M z@2&O^#0>img7B4$*2O>jh1je*I`T0$7*&a+$rg0Yh&2g zZmyNnIzEyvk*Lj>b7N5z3BvAxkzyO`aD7k;9t|R7%f5}B)bTVx2!H$ta2XbdBqTrVjKxEl;K_uUKWPg|M}gPhlYHX~ zZD>NxdU3jYBS{T$1*tL;LAATqhD}i2tYN3>_2FDYl&9i&EXM_-S)NYJ&ISTw1A!R! z4WIXLZjICnSQ7ZRTELdpgBQ1K!*Vr(dArhcwpW-tH*E+T1zZUl9wZ7s+!As3*YCRa zv>AIw8?5cq%yau=DL{VHa=IIQG8s&3lGu=6oaKxhoxvL;tCp`rb#~AG9#Tf0+F=2s z^>j#Bv)rANqo&T;Q^57|ipKFB)3Ae^_iEU*YGjiB7x(L$Iq8qqA7O(=XBZ4Tf@2jR z6YqRMvs_KcpvglTt5ax5|K8%go9YDO`!E}{WGXtsYPH_RaQDo-}DU}Bg{+C`uexU zEyl3iUJIUs2s3XdDx3=jf(M|Ac0wgP-FKDu^7aClo$V>Xn>})0kYz!HbVagj(gPy} z+V~f05PW1irsgGnh+mF{u)@2ayNlN>gJl{chl3D{jJ>qWlCYF7qoXw|a-@d@k_J1Sn z>)b|*(aT}su=zA5QRnE}Ju1xgGXc5=9^~og&G%OKxE9@1zFM%7g;i)~lx3D34a%0AW2*I$B6Ajy7D&(+>%QsyYVIg&%6meXu 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 literal 0 HcmV?d00001 diff --git a/docs/source/images/topics/xcom_reg_timing.png b/docs/source/images/topics/xcom_reg_timing.png new file mode 100644 index 0000000000000000000000000000000000000000..89313c6c24574576fcb56955fbf42061899077bc GIT binary patch literal 38557 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 literal 0 HcmV?d00001 diff --git a/docs/source/images/topics/xcom_waves.png b/docs/source/images/topics/xcom_waves.png new file mode 100644 index 0000000000000000000000000000000000000000..b272e7c205a4f4af5ed98b81ac6a5cfdee2029fe GIT binary patch literal 11400 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 literal 0 HcmV?d00001 diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 000000000..6b193c18a --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,185 @@ +.. Sphinx Apidoc Tutorial documentation master file + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to the QICK documentation! +================================================= + +.. figure:: ../../graphics/QICK.jpg + :width: 100% + :align: center + +.. figure:: ../../graphics/ZCU216Board.jpg + :width: 100% + :align: center + +What is QICK? +============== + +The **Quantum Instrumentation Control Kit (QICK)** is an AMD RFSoC-based qubit controller +that supports the direct synthesis of control and readout pulses for quantum computing experiments. + +QICK consists of: + +- **Hardware**: AMD RFSoC board (ZCU111, ZCU216, or RFSoC4x2) with optional custom analog front-end +- **Firmware**: Custom FPGA logic including tProcessor, DDS generators, and readout system +- **Software**: Python library for pulse programming, data acquisition, and real-time feedback + +All schematics, firmware, and software are **open-source** and available on GitHub. + +Key Features +------------- + +- **Real-time control** with tProcessor (multi-core, < 10 ns timing resolution) +- **Direct RF synthesis** up to 6 GHz (ZCU216) without external mixers +- **Multi-tone generation** with phase-coherent muxed generators +- **Real-time feedback** and conditional logic +- **High-speed data streaming** and on-FPGA processing +- **Custom firmware** support via AXI-lite interface + +Quick Links +============ + +- **Source Code**: `GitHub Repository `_ +- **Firmware**: `qick/firmware `_ +- **QICK Paper**: `arXiv:2110.00557 `_ +- **Community**: :repofile:`Contact & Support ` + +Extensions & Customization +=========================== + +- **Pyro4 Server**: Persist board state across notebooks (`Pyro4 demos `_) +- **QCoDeS Driver**: Save instrument configuration (`QCoDeS-QICK `_) +- **QICK-DAWG**: NV centers and quantum defects (`GitHub `_) +- **SpinQICK**: Solid-state spin qubits (`GitHub `_) + +📖 Documentation Navigation +============================ + +The documentation is organized as a **progressive learning path** from beginner to expert. + +.. toctree:: + :maxdepth: 2 + :caption: 1. Getting Started + + quick_start + +.. toctree:: + :maxdepth: 2 + :caption: 2. Jupyter Notebook Tutorials + + tutorials/00_Getting_Started + tutorials/01_Basic_Sequencing + tutorials/02_Parameter_Sweeps + tutorials/03_Advanced_Timing + tutorials/04_Real_Time_Feedback + tutorials/05_Dynamic_Parameters_Subroutines + tutorials/06_Generators_And_Readouts + tutorials/07_Advanced_Generators_And_Readouts + tutorials/08_Hardware_Buffers + tutorials/09_Appendix_Tips_And_Limits + tutorials/10_Multi_Board_Synchronization + tutorials/11_Streaming_And_RealTime_Processing + tutorials/12_DSP_Blocks_And_Correlators + tutorials/13_Custom_Firmware_Integration + tutorials/14_XCOM_Network_Synchronization + +.. toctree:: + :maxdepth: 2 + :caption: 3. Hardware & Firmware Reference + + tprocv2_trm + tprocv1 + firmware + +The **readout system** turns ADC samples into the I/Q data your program gets +back. QICK offers several down-converter and buffer cores with different +tradeoffs (software- vs. tProc-configured, on-chip BRAM vs. DDR4 capture, +plus a resonator simulator for hardware-in-the-loop testing) -- start at +:doc:`readout` for the concepts and the normal ``declare_readout()``/ +``acquire()`` workflow, then dip into a specific core's page for register- +level detail. + +.. toctree:: + :maxdepth: 2 + :caption: 4. Readout System + + readout + readout_v2 + readout_dynamic + readout_pfb + avg_buffer + mr_buffer_et + kidsim + +The **signal generators** turn your program's pulse definitions into DAC +output. QICK offers both single-tone arbitrary-envelope generators (for +shaped pulses) and multiplexed fixed-tone generators (for playing several +simultaneous tones from one channel) -- start at :doc:`generators` for an +overview of which core fits which experiment, then see :doc:`sg_v6` for the +full worked Python examples shared across the family. + +.. toctree:: + :maxdepth: 2 + :caption: 5. Signal Generators + + generators + sg_v6 + sg_mux8 + sg_mixmux8 + sg_int4_v2 + sg_v4 + +The **support & utility cores** are smaller IP blocks -- a constant-IQ tone +source, a tProc-output register/trigger helper, and an AXI-Stream buffering +core -- that don't fit into either the readout or signal-generator families +above; see :doc:`support_cores` for what each one does and how (or whether) +it's exposed to Python. + +.. toctree:: + :maxdepth: 2 + :caption: 6. Support & Utility Cores + + support_cores + +.. toctree:: + :maxdepth: 2 + :caption: 7. Technical Topics + + topics/index + +.. toctree:: + :maxdepth: 2 + :caption: 8. Python API Reference + + modules + +.. toctree:: + :maxdepth: 2 + :caption: 9. Community + + contact + papers + +Learning Path Recommendations +============================== + +**New to QICK?** Start here: + +1. Read the :doc:`quick_start` guide to set up your board +2. Complete the **Basic Tutorials** (00-05) to understand core concepts +3. Work through **Intermediate Tutorials** (06-09) for practical measurements +4. Explore **Advanced Tutorials** (10-13) for specialized applications + +**Already familiar with QICK?** Jump directly to: + +- :doc:`tprocv2_trm` for tProcessor instruction reference +- :doc:`readout` and :doc:`generators` for the readout/generator hardware + reference, organized by which core is on your channel +- :doc:`topics/index` for deep dives on specific topics +- :doc:`modules` for full API documentation + +Academic Papers +================ + +For a list of academic papers published using the QICK system, see :doc:`papers`. diff --git a/docs/source/kidsim.md b/docs/source/kidsim.md new file mode 100644 index 000000000..facb475a5 --- /dev/null +++ b/docs/source/kidsim.md @@ -0,0 +1,472 @@ +# KID / Qubit Resonator Emulator (axis_kidsim_v3) + +```{contents} +:local: +:depth: 2 +``` + +```{note} +This page documents the **fusesoc-ported** `axis_kidsim_v3` (register model +and driver under `firmware/fusesoc/cores/ip/axis_kidsim_v3/`), which was +still in progress and not yet merged at the time this page was written. A +legacy Vivado-packaged version of the same algorithm exists at +`firmware/ip/axis_kidsim_v3/`; the RTL (`kidsim`/`kidsim_top`) is the same +design, but that legacy IP has no `qick_lib` driver. +``` + +**axis_kidsim_v3** is not a readout -- it's a per-lane RF resonator +simulator, used to test KID/qubit readout firmware and software against a +physically-realistic resonator response without a real cryostat. Each lane +demodulates its input with a DDS carrier, applies a 1-pole/1-zero IIR at +baseband (the resonator response), and remodulates back to RF. The module +lives at `firmware/rtl_lib/ip/axis_kidsim_v3.sv` (top level) / +`firmware/rtl_lib/ctrl/kidsim_top.sv` / `kidsim.sv` (per-lane core), and is +exposed to Python through `AxisKidsimV3` +(`firmware/fusesoc/cores/ip/axis_kidsim_v3/driver/axis_kidsim_v3.py`). + +## 1. General Description + +`axis_kidsim_v3` wraps `L` parallel `kidsim_top` lanes behind one AXI4-Lite +register block. Each lane processes one 32-bit {Q, I} sub-word of the packed +AXI-Stream input (`s_axis_tdata` is `32*L` bits total). Per-lane +configuration (DDS/IIR/output-select/puncturing registers) is written +through a shared register set and latched into the target lane by writing +`ADDR_REG` (the lane index) then pulsing `WE_REG`. + +## 2. Synthesis Parameters + +```{list-table} +:header-rows: 1 +:widths: 20 15 65 + +* - Parameter + - Default + - Description +* - `L` + - 8 + - Number of parallel lanes (independent simulated resonators). +``` + +## 3. Register Map + +All registers are 32-bit, byte-addressed, `sw=rw`/`hw=r` (software writes, +hardware reads) unless noted. From +`firmware/fusesoc/cores/ip/axis_kidsim_v3/rdl/axis_kidsim_v3_regmap.rdl`. + +```{list-table} +:header-rows: 1 +:widths: 20 10 15 55 + +* - Register + - Addr + - Width + - Description +* - `DDS_BVAL_REG` + - 0x00 + - 16 (signed Q15) + - Chirp ramp start value B. `ramp(n) = B - n*M` for `n` in `[0, N]`. +* - `DDS_SLOPE_REG` + - 0x04 + - 16 (signed Q15) + - Chirp ramp slope M per step. +* - `DDS_STEPS_REG` + - 0x08 + - 16 + - Number of chirp ramp steps N. +* - `DDS_WAIT_REG` + - 0x0C + - 16 + - Wait cycles per chirp step W (0 = one step/cycle). +* - `DDS_FREQ_REG` + - 0x10 + - 16 + - DDS base phase increment (carrier frequency); `pinc(n) = FREQ - ramp(n)`. +* - `IIR_C0_REG` + - 0x14 + - 16 (signed Q15) + - IIR feed-forward (zero) coefficient C0. See §4 for the physical meaning. +* - `IIR_C1_REG` + - 0x18 + - 16 (signed Q15) + - IIR feed-back (pole) coefficient C1 -- sets the resonator linewidth. +* - `IIR_G_REG` + - 0x1C + - 16 (signed Q15) + - IIR output gain G (`0x7FFF` ~= 1.0). +* - `OUTSEL_REG` + - 0x20 + - 2 + - Output select: 0=processed signal (demod/IIR/remod), 1=DDS carrier only, 2=input bypass (default), 3=zero. +* - `PUNCT_ID_REG` + - 0x24 + - 16 + - Puncturing: which sample index within a frame is selected for output. +* - `ADDR_REG` + - 0x28 + - 8 + - Target lane index for the next configuration write. +* - `WE_REG` + - 0x2C + - 1 + - Write enable -- pulse 1 (with `ADDR_REG` already set) to latch the above registers into that lane. Latches all registers together: a frequency-only update must rewrite `C0`/`C1`/`G` with their existing values too, or it will perturb the resonator. +``` + +Pass-through configuration (no filtering, unity gain): `C0=0`, `C1=0`, +`G=0x7FFF`. + +## 4. Python Interface + +`AxisKidsimV3` (`bindto = ['qick:ip:axis_kidsim_v3:1.0']`) is a thin, +PeakRDL-generated register-model wrapper -- as of this writing it exposes +only raw register access via `.regs` (e.g. `ip.regs.IIR_C1_REG.C1.write(...)`, +matching the field names in the register map above), with the file's +`# -- hand-written high-level methods below --` marker left as a +placeholder for higher-level convenience methods (e.g. a +"configure resonator" helper) not yet written. There is also a +standalone Python behavioral model, `model/kidsim_resonator.py` (with an +accompanying `model/kidsim_resonator_demo.ipynb`), useful for prototyping +resonator parameters offline before writing them to hardware. + +## 5. Resonator Physics -- Design Note + +The rest of this page is the design note for the emulator's physical model: +what the IIR/DDS register values correspond to in terms of resonator +properties (linewidth, Q, coupling), what physical readout topology it +implements, and how a mid-readout ground/excited frequency jump behaves. + +**Modules:** `kidsim_top` → `kidsim` → (`dds_chirp`, `cmult`, `iir_iq` → +`iir_1p1z`) + +### 5.1. What the emulator does + +Each lane simulates one resonator by **demodulating** the incoming stream +with a DDS carrier, **filtering** the resulting complex baseband with a +first-order (1-pole/1-zero) IIR, and **remodulating** back to RF: + +``` +din --[din_la = DDS_LATENCY]---------------------\ + prod0 = din . e^{-jf} (CONJB=1, demod) +dds_chirp --> e^{jf(t)} ---------------------------/ + | | + | iir_iq (H(z), per I and Q) + | | + \--[dds_dout_la = 8]--> e^{jf} -----------------> prod1 = iir . e^{+jf} (remod) +``` + +The IIR runs on the **demodulated** (baseband) signal, so its passband is +centred at DC in the rotating frame. Remodulation shifts that passband back +up to the carrier frequency $f_c$. The net effect from `din` to `prod1` is +therefore a **band-pass resonator centred at the carrier**, with its shape +set by the IIR coefficients. + +The IIR itself (`iir_1p1z`) is Direct-Form I: + +$$H(z) = G\,\frac{1 - C_0 z^{-1}}{1 - C_1 z^{-1}}$$ + +with $C_0, C_1, G$ signed $Q(B-1)$ in $[-1, +1)$ and a real pole at $z = C_1$. +`iir_iq` applies this **independently** to the I and Q components with the +same real coefficients, so in the rotating frame it is a complex-baseband +filter with a **real** pole sitting at baseband DC. + +**Key structural fact for everything below:** the resonant frequency is set +by the *carrier* (`DDS_FREQ_REG`), **not** by the pole. The pole (`C1`) sets +the linewidth; the zero (`C0`) sets the coupling; the gain (`G`) sets the +overall scale. Switching "ground" <-> "excited" is a change of +`DDS_FREQ_REG`. + +### 5.2. From baseband filter to band-pass resonator + +Let the carrier phase be $\varphi[n]$ (for a CW tone, $\varphi[n] = \omega_c n$, +$\omega_c = 2\pi f_c/f_s$). Demod multiplies by $e^{-j\varphi}$, the IIR +applies $H(e^{j\omega})$ at baseband, remod multiplies by $e^{+j\varphi}$. +For a CW carrier the composite response from input to output is a +**frequency-shifted** copy of the baseband filter: + +$$H_\text{bp}(e^{j\omega}) = H\!\left(e^{j(\omega - \omega_c)}\right)$$ + +So the low-pass $H$ (real pole near DC) becomes a band-pass centred at +$\omega_c$. All the resonator physics is in $H$; the carrier only says +*where* the resonance sits. + +### 5.3. Scale factors -- IIR/DDS registers -> resonator properties + +Let $f_s$ be the sample rate at the IIR, $N$ the DDS phase-accumulator +width, and write the pole as $C_1 = 1 - \varepsilon$ with $\varepsilon \ll 1$ +(high-Q regime). + +```{list-table} +:header-rows: 1 +:widths: 30 40 30 + +* - Resonator property + - Expression + - Set by +* - Resonant frequency + - $f_0 = f_c = \dfrac{\text{DDS\_FREQ\_REG}}{2^{N}}\,f_s$ + - `DDS_FREQ_REG` (carrier) +* - Field decay rate + - $\kappa/2 = (1 - C_1)\,f_s$ + - `C1` (pole) +* - Energy decay rate (loaded linewidth) + - $\kappa = 2(1 - C_1)\,f_s$ + - `C1` +* - FWHM (Hz) + - $\dfrac{\kappa}{2\pi} = \dfrac{(1 - C_1)\,f_s}{\pi}$ + - `C1` +* - Loaded quality factor + - $Q_L = \dfrac{\pi f_0}{(1 - C_1)\,f_s}$ + - `C1`, `DDS_FREQ_REG` +* - Ringdown time (field) + - $\tau = \dfrac{1}{(1 - C_1)\,f_s}$ + - `C1` +* - On-resonance response + - $H(1) = G\,\dfrac{1 - C_0}{1 - C_1}$ + - `G`, `C0`, `C1` +``` + +**Derivation of the linewidth.** The pole's impulse response is +$\propto C_1^{\,n} = e^{n\ln C_1} \approx e^{-\varepsilon n}$ for +$C_1 = 1-\varepsilon$. In continuous time ($t = n/f_s$) the field envelope +decays as $e^{-\varepsilon f_s t} = e^{-\kappa t/2}$, giving +$\kappa/2 = (1-C_1)f_s$. The power spectrum of a field decaying at $\kappa/2$ +is a Lorentzian of FWHM $\kappa$ (rad/s), i.e. $(1-C_1)f_s/\pi$ in Hz, and +$Q_L = \omega_0/\kappa = 2\pi f_0/\kappa$ follows. The $(1-C_1)$ form is the +high-$Q$ limit; the **exact** per-clock decay is $|y_1|[n]\propto C_1^{\,n}$ +(xsim-confirmed), so $\kappa = -2\ln(C_1)\,f_s$ exactly. At $C_1=0.9$ the two +differ by ~5%; for any realistic high-$Q$ resonator ($C_1\to1$) they +coincide. + +> **Sanity check against the code.** The header notes numerical fidelity +> measured with `C0=0, C1=0, G=32767` (~=0.99997). That is the *pass-through* +> limit: pole at DC, no filtering, $H(1) = G(1-0)/(1-0) = G \approx 1$. The +> residual ~3 LSB error is the $G = 32767/32768 \ne 1$ offset plus IIR +> truncation and the two `cmult` round stages -- consistent with the table. + +### 5.4. What physical configuration this is + +The 1-pole/1-zero shape is exactly the response of a **single-mode resonator +in a notch / hanger geometry** (equivalently a reflection measurement). The +standard hanger transmission is + +$$S_{21}(\Delta) = 1 - \frac{\kappa_c/2}{j\Delta + \kappa/2}, \qquad \Delta = \omega - \omega_0,\ \ \kappa = \kappa_i + \kappa_c,$$ + +which is a bilinear (Mobius) function of frequency -- precisely a +1-pole/1-zero rational form. Rearranging, + +$$S_{21}(\Delta) = \frac{j\Delta + \kappa_i/2}{j\Delta + \kappa/2},$$ + +so on resonance $S_{21}(0) = \kappa_i/\kappa$ (notch depth) and far off +resonance $S_{21} \to 1$. This is the readout topology used in cQED -- so +**the current IIR is already the right physical model**, not an +approximation to be replaced. + +Matching $H(z)$ to $S_{21}$ at baseband DC ($z=1$) gives a clean coupling +interpretation: + +```{list-table} +:header-rows: 1 +:widths: 25 75 + +* - Filter quantity + - Physical meaning +* - $1 - C_1$ + - total (loaded) linewidth $\kappa = \kappa_i + \kappa_c$ +* - $1 - C_0$ + - internal loss $\kappa_i$ +* - $C_0 - C_1$ + - coupling $\kappa_c$ +* - $\dfrac{1-C_0}{1-C_1}$ + - notch depth $\kappa_i/\kappa$ (1 = shallow/undercoupled, 1/2 = critical, ->0 = deep/overcoupled) +* - $G$ + - off-resonance baseline (set ~= 1 for a passive notch) +``` + +So today's `C0 = 0` means $\kappa_i = \kappa$ -- i.e. **fully +internally-limited, no external coupling contrast** (the "resonator" has no +notch, it's just the pole). To get a realistic notch you set $C_0$ **near** +$C_1$, with the small gap $C_0 - C_1$ encoding $\kappa_c$. + +**Where a more realistic IIR would help** (candidates for v4, in priority +order): + +1. **Compute coefficients from physics, don't hand-tune.** Given target + $\kappa_i, \kappa_c, \omega_0$, derive $C_0, C_1, G$ via a bilinear (or + matched-z) transform of $S_{21}$. This makes the register values mean + something and makes ground/excited a physics parameter set. +2. **Complex gain for Fano asymmetry.** Real resonators show an asymmetric, + rotated notch (impedance mismatch / cable delay -- the $a\,e^{j\phi}$ + prefactor in the Khalil notch model). A real `G` cannot produce it; a + complex gain (an I/Q rotation) can. There is already a `cmult` in the + chain to fold this into. +3. **Warping is negligible.** Because the resonator bandwidth $\ll f_s$, + bilinear frequency warping is not worth correcting; the real-pole-at- + baseband-DC discretisation is fine. + +### 5.5. Ground/excited switching and the stored field + +The physically interesting question: *when the resonator frequency jumps +mid-readout, there is stored energy with a definite phase -- is it handled +correctly?* + +**Where the stored field lives.** The intracavity field envelope is the IIR +feedback state. In each `iir_1p1z` it is `y1` (the saturated pole state +`y1_r1a`/`y1_r1b`); the I and Q cores together hold the **complex** +intracavity envelope, expressed in the frame rotating at the carrier. + +**The jump mechanism.** A jump changes the carrier frequency (`dds_freq_r` +-> `pinc`). The pole `C1` is unchanged, so the linewidth $\kappa$ is +preserved -- correct: the cavity's loss rate doesn't change when its +frequency does. Because the pole sits at baseband DC in *both* the old and +new frames, the stored field's ringing frequency snaps to the new +$\omega_0$ with no transient *in the frame*, the correct linear-resonator +behaviour (the eigenfrequency is a cavity property and changes instantly; +the field amplitude and phase are continuous). + +**The three correctness conditions, now checked against the RTL:** + +1. **DDS phase continuity -- SATISFIED by construction.** `dds_phase_ctrl` + emits the control word `{phase=0, pinc}` with `pinc = FREQ_REG - ramp(n)` + and a *constant* phase-offset field of 0. The phase **accumulator lives + inside the DDS IP** (`dds_phasegen_sincos_ow16_lat8`) and integrates the + streamed `pinc`; changing `FREQ_REG` changes the *increment* (the slope), + not the accumulated value, so the carrier phase is continuous across the + change -- the lab-frame field cannot teleport. The controller also + advances its datapath only on `i_din_valid`, so bubbles hold the + sequence rather than jumping it. *(One residual check: eyeball the DDS + behavioural model to confirm the accumulator is free-running and never + reloaded -- the streaming-`pinc` / fixed-`POFF=0` control word is exactly + the phase-continuous configuration, so this is expected.)* +2. **IIR state preserved -- SATISFIED.** The `y1` pole registers reset only + on `~i_rstn`. A config write (`WE`) latches only the coefficient/frequency + registers; nothing in the write path clears the IIR datapath. State + carries across the jump. *(Usage note: `WE` latches all registers + together, so a frequency-only jump must rewrite `C0`/`C1`/`G` with their + existing values to avoid perturbing the linewidth.)* +3. **No cancellation-breaking transient -- the earlier concern was wrong.** + Remod reuses the **identical carrier sample** that demod used: + `dds_dout_la = dds_dout` delayed by exactly `prod0(4) + iir(4) = 8`, which + is the pipeline latency between the two multipliers. So `prod1[t]` + multiplies by `dds_dout[t-8]` and `iir_out[t]` was demodulated by + `conj(dds_dout[t-8])` -- the same sample -- giving + $e^{-j\varphi}e^{+j\varphi}=1$ **sample-for-sample, for any carrier + trajectory including a step**. The `din_la = DDS_LATENCY = 10` tap + likewise aligns each input sample with the frequency commanded when it + entered. There is no spurious pipeline glitch at the jump. + +**Verdict:** at the datapath level the emulator handles a mid-readout jump +*physically correctly* -- the stored field keeps its amplitude and phase, +immediately rings at the new frequency, and decays at the unchanged +$\kappa/2$, with the drive now at the new detuning building the new steady +state. The one real transient is the physical one (old field ringing down +while the new one builds), which is exactly what we want. + +**The genuine v4 gap is the switching *mechanism*, not the datapath.** +Neither existing path cleanly does a *triggered, persistent, +phase-continuous* step between two resonant frequencies: + +- The **chirp/trigger** path (`i_trigger` -> `ramp_gen`) sweeps `pinc` for + `N` steps and **settles back to `FREQ_REG`** -- a sweep-and-return, not a + persistent two-level switch. +- The **register write** of `DDS_FREQ_REG` is persistent but not + time-deterministic (AXI + `WE` CDC latency; and `WE` is a + software-pulsed bit crossing clock domains -- the classic + sim-passes/hardware-flakes hazard). + +For ground<->excited "on demand, triggered from the tProc at a precomputed +time," v4 wants a small **triggered frequency-select** (e.g. two latched +`FREQ` values and a per-lane trigger that toggles which one drives `pinc`), +keeping the accumulator free-running so the switch stays phase-continuous. +This is the one new bit of RTL the jump actually needs. + +### 5.6. Latency reference (from the RTL) + +```{list-table} +:header-rows: 1 +:widths: 40 20 40 + +* - Path + - Cycles + - Source +* - DDS block + - `DDS_LATENCY = 10` + - `dds_phase_ctrl (2) + DDS IP (8)` +* - `din` alignment to carrier + - `din_la = DDS_LATENCY = 10` + - fixes chirp demod alignment +* - Carrier reuse demod->remod + - `dds_dout_la = 8` + - `prod0 (4) + iir (4)` -- guarantees $e^{-j\varphi}e^{+j\varphi}=1$ +* - `kidsim` main path + - `10 + 4 + 4 + 4 = 22` + - DDS + prod0 + iir + prod1 +* - `kidsim_top` total + - `24` + - `punct (2) + KIDSIM_LAT (22)` +``` + +Two independent timing constraints not to conflate (per the `kidsim` +header): `dds_dout_la = 8` guarantees carrier cancellation for *any* input; +`din_la = DDS_LATENCY` selects *which* input sample is demodulated at each +instantaneous chirp frequency and only matters when the input varies in +time. + +### 5.7. Validation plan (what a demonstrating notebook should show) + +A short QICK notebook (or xsim testbench) can turn the theory above into +measured numbers: + +1. **Linewidth / Q.** Sweep the probe across $f_0$, measure the transmitted + magnitude, fit a Lorentzian, and check FWHM $= (1-C_1)f_s/\pi$ and + $Q_L = \pi f_0/((1-C_1)f_s)$ against the table for a few `C1` values. +2. **Ringdown.** Drive on resonance to steady state, switch the drive off, + fit the decay, and check $\tau = 1/((1-C_1)f_s)$. +3. **Notch depth vs coupling.** Set $C_0$ near $C_1$, sweep the gap + $C_0 - C_1$, and confirm the on-resonance depth tracks + $\kappa_i/\kappa = (1-C_0)/(1-C_1)$. +4. **The jump (the important one).** Reach steady state, jump + `DDS_FREQ_REG` (ground->excited), and plot the lab-frame output through + the transition. Confirm: field amplitude/phase continuous, new-frequency + ringing, decay at the unchanged $\kappa/2$. This is also the test that + surfaces condition (1)/(3) of §5.5 if the DDS is not phase-continuous. +5. **Fake T1.** Trigger the ground->excited jump from the tProc at a + precomputed time and show the readout following the programmed decay. + +**Characterization notes (measured in xsim):** + +- The datapath advances **every clock**, not per input beat: the DDS IP + free-runs its output valid, so `dds_valid` (hence `prod0`/IIR/`prod1`) is + asserted every cycle regardless of how sparse `din_valid` is. The + `iir_1p1z` bubble-gating is therefore moot under a running carrier. + Consequence for the scale factors: the decay is $C_1$ **per clock**, so + $\tau = 1/((1-C_1)f_s)$ is per-sample-at-$f_s$ exactly as in §5.3 -- + confirmed by a ringdown showing $|y_1|[n]=|y_1|[0]\,C_1^{n}$ per clock. (A + test that streams sparse beats measures $C_1^{\text{gap}}$ per beat and + looks wrong; drive contiguously.) +- A small **DC floor** sits under the ringdown: the two `cmult` stages use + round-half-up (`ROUND=1`), whose $+\tfrac12$ LSB bias is integrated by the + pole to $\approx \text{bias}/(1-C_1)$ (~=13 LSB at $C_1=0.9$). Harmless for + the emulation, but measure the linewidth well above it. + +### 5.8. Open items feeding v4 + +- Decide whether to keep hand-tuned `C0`/`C1`/`G` or add a + **physics->coefficient** helper (bilinear transform from + $\kappa_i,\kappa_c,\omega_0$). Recommended. +- Decide whether Fano asymmetry matters for the intended use; if so, add a + **complex gain** stage. +- §5.5 conditions (1)-(3) are **resolved in RTL**: phase-continuous DDS, + preserved IIR state, exact carrier cancellation through a step. The + remaining jump work is the **triggered persistent frequency-select** (two + latched `FREQ` values + per-lane trigger, accumulator kept free-running), + and the residual DDS-model eyeball of condition (1). Lock the datapath + behaviour with the jump test of §5.7.4. +- This note documents the **passive resonator**. The **active RF qubit + emulator** (DDS LO + Bloch-state registers + demod-driven state rotation + -> Rabi) is a separate v4 datapath and gets its own note. + +## Related Documentation + +* {doc}`/readout` and {doc}`/avg_buffer` -- the real readout chain this IP + emulates a resonator in front of, for hardware-in-the-loop testing. +* `firmware/fusesoc/cores/ip/axis_kidsim_v3/model/kidsim_resonator_demo.ipynb` + -- Python behavioral model / demo notebook. diff --git a/docs/source/modules.rst b/docs/source/modules.rst new file mode 100644 index 000000000..ba2dd52c1 --- /dev/null +++ b/docs/source/modules.rst @@ -0,0 +1,99 @@ +Software API +============ + +This page is the raw, auto-generated API reference -- every public class, +method, and function in ``qick_lib``, with its docstring. For most tasks +you don't need to browse it directly: the narrative pages +(:doc:`/generators`, :doc:`/readout`, :doc:`/tprocv2_trm`, ...) already +link to the specific method you need via cross-references. Come here when +you need the full signature/parameter list for something, or want to see +everything a class exposes at a glance. + +The modules are grouped below by what you'd actually reach for them for, +not alphabetically. + +Writing programs +----------------- + +The classes you subclass and call directly when writing an experiment. +:mod:`qick.asm_v2` is the current tProc v2 API (used throughout this doc +set); :mod:`qick.asm_v1`/:mod:`qick.averager_program` are the legacy tProc +v1 equivalent (see :doc:`/tprocv1`). :mod:`qick.qick_asm` holds the base +classes and methods (``declare_gen``, ``declare_readout``, ``add_pulse``, +``add_envelope``, ...) shared by both. + +.. autosummary:: + :toctree: _autosummary + + qick.qick_asm + qick.asm_v2 + qick.asm_v1 + qick.averager_program + +Connecting to the board +------------------------- + +.. autosummary:: + :toctree: _autosummary + + qick + qick.qick + qick.rfboard + qick.pyro + +:class:`.QickSoc` (:mod:`qick.qick`) is the main entry point -- instantiate +it once, then reach every generator/readout/buffer/tProc driver through its +``soc.gens``/``soc.readouts``/``soc.avg_bufs``/``soc.tproc`` arrays (see +:doc:`/firmware` for what's on your board). :mod:`qick.rfboard` extends it +for boards with an external RF front-end. :mod:`qick.pyro` lets you connect +to a board running headless over the network instead of locally. + +Hardware drivers +------------------- + +You'll interact with these through the ``soc.gens``/``soc.readouts``/ +``soc.avg_bufs``/``soc.tproc`` arrays above, not by importing these +modules directly -- see :doc:`/generators`, :doc:`/readout`, and +:doc:`/tprocv1`/:doc:`/tprocv2_trm` for the driver classes' individual +pages (register maps, RTL cross-references) rather than the bare +docstrings here. + +.. autosummary:: + :toctree: _autosummary + + qick.drivers.generator + qick.drivers.readout + qick.drivers.tproc + +Assembly and compilation internals +------------------------------------- + +Normal programs don't call these directly -- :mod:`qick.asm_v2`/ +:mod:`qick.asm_v1` invoke them for you. Useful if you're debugging a +compiled program or working with raw assembly text (see +:doc:`topics/asmv2_cheatsheet`). + +.. autosummary:: + :toctree: _autosummary + + qick.tprocv2_assembler + qick.parser + +Utilities and framework internals +------------------------------------- + +.. autosummary:: + :toctree: _autosummary + + qick.helpers + qick.streamer + qick.ip + +:mod:`qick.helpers` holds small standalone support functions. +:mod:`qick.streamer` is :class:`.DataStreamer`, a polling thread for +continuous acquisition -- not a driver for a specific IP core (see +:doc:`/support_cores` if you were looking for the ``axis_streamer`` RTL +block instead, a different thing despite the name). :mod:`qick.ip` has the +base :class:`.SocIP`/:class:`.QickIP` driver classes and the board metadata +tracing every driver's ``configure_connections()`` uses -- framework +internals, only relevant if you're writing a new driver. diff --git a/docs/source/mr_buffer_et.rst b/docs/source/mr_buffer_et.rst new file mode 100644 index 000000000..cd67a8735 --- /dev/null +++ b/docs/source/mr_buffer_et.rst @@ -0,0 +1,402 @@ +======================================================== +Multi-Rate Buffer (mr_buffer_et) - QICK Firmware +======================================================== + +.. contents:: + :local: + :depth: 2 + +The **Multi-Rate buffer with External Trigger** (``mr_buffer_et``) is a +small on-chip capture buffer that taps a readout's *undecimated* data +stream -- the downconverted but not-yet-decimated samples, straight out of +the digital mixer, before the readout's FIR/decimate-by-N stage. This is in +contrast to :doc:`/avg_buffer`'s raw buffer and the DDR4 buffer +(``axis_buffer_ddr_v1``), which both see the *decimated* stream. Because it +sits upstream of decimation, ``mr_buffer_et`` sees the full ADC-rate signal +(useful for looking at spurs, noise, or transient/settling behavior that +decimation would filter out), at the cost of a much smaller capture depth +(on-chip BRAM, not DDR4). The module lives in the ``qick`` firmware +repository under ``firmware/ip/mr_buffer_et/`` and is exposed to Python +through ``qick.drivers.readout.MrBufferEt``. + +.. note:: + + The RTL under ``firmware/ip/mr_buffer_et/src/`` (``mr_buffer_et.sv``) is + a SystemVerilog rewrite whose file header identifies it as VLNV + ``qick:ip:mr_buffer_et:1.2.0`` / ``@version 1.2``. However, as of this + writing the packaged ``component.xml`` in the same directory (Xilinx IP + packager metadata) still lists the legacy VHDL sources + (``mr_buffer_v1_0.vhd`` and friends) and reports IP version ``1.1``, and + the Python driver's ``bindto`` list (``qick_lib/qick/drivers/readout.py``) + only recognizes VLNVs ending in ``:1.0`` and ``:1.1``. Board designs + checked in this repository (e.g. + ``firmware/projects/qick_tprocv2_111_standard/bd_2023-1.tcl``) also + instantiate ``QICK:QICK:mr_buffer_et:1.1``. This document describes the + behavior of the SystemVerilog source in ``src/`` (which is what a fresh + IP-XACT repackage would pick up), and calls out anywhere that source + adds behavior (the ``STATUS``/``capture_done`` register, notably) that + the current driver does not yet use. It was **not** verified against the + actual synthesized bitstream of any specific board release -- the two + register fields the driver does use (``dw_capture_reg``, + ``dr_start_reg``) are unchanged between the VHDL and SystemVerilog + implementations, so this is not expected to matter in practice. + +-------------------------------------------------------------------- +1. General Description +-------------------------------------------------------------------- + +``mr_buffer_et`` (top level ``mr_buffer_et.sv``, wrapping the core +``mr_buffer.sv``) captures ``NM`` parallel channels of ``B`` bits each into +``NM`` independent BRAMs (depth ``2**N`` per BRAM) at full write-side rate +(``s_axis_aclk``). A capture is armed in software (``dw_capture_reg=1``) +and then started by an external hardware ``trigger`` input; once the +window fills, the captured data is drained out as a single ``B``-bit +AXI4-Stream on the read side (``m_axis_aclk``) when software pulses +``dr_start_reg=1``. Per the module's own header comment +(``firmware/ip/mr_buffer_et/src/mr_buffer_et.sv``), the intended flow is: + +1. SW writes ``dw_capture_reg=1`` -- arm the writer. +2. External ``trigger`` fires -- BRAMs fill with ``2**N`` samples/channel. +3. SW writes ``dr_start_reg=1`` -- stream the whole window out. +4. AXI-DMA S2MM drains ``M_AXIS`` to memory (read burst = ``NM*2**N`` + beats, ending in ``tlast``). + +The ``NM`` parallel input channels exist because the source data arrives +faster than one sample per fabric clock: per the QICK demo notebook +(``qick_demos/08_Special_buffers.ipynb``), the MR buffer "is fed by the +downconverted but undecimated data stream coming out of the readout, so +you get 8 samples per fabric tick, or 1 sample per ADC tick." This lines +up with the RTL: ``axis_dyn_readout_v1``'s downsampling ratio is 8 +(``DOWNSAMPLING = 8`` on ``AxisDynReadoutV1`` in +``qick_lib/qick/drivers/readout.py``), and the default synthesis parameter +is ``NM=8`` -- so in typical firmware images, one fabric-clock beat of the +undecimated stream carries all ``NM`` samples that will land at ``ADC +rate`` in real time, and ``mr_buffer_et`` writes all ``NM`` of them into +``NM`` separate BRAMs in that same beat. + +In board designs (see e.g. +``firmware/projects/qick_tprocv2_111_standard/bd_2023-1.tcl``), +``mr_buffer_et`` sits downstream of a many-to-one AXI4-Stream switch +(``axis_switch_mr``) whose inputs are the ``m0_axis`` ports of the board's +dynamic readouts (``axis_dyn_readout_v1``) -- the undecimated tap; compare +with the ``m1_axis`` port of the same readouts, which is the decimated +stream that feeds :doc:`/avg_buffer`. Its own ``m00_axis`` output feeds an +AXI-DMA (``axi_dma_mr``) that drains captured data to PS-side (CPU) +memory. In that same board design the instance is parameterized with +``B=32`` (a packed 16-bit I / 16-bit Q sample) and ``N=10`` (1024-deep +per-channel BRAM), leaving ``NM`` at its RTL default of 8 -- giving a +total capacity of ``8*1024 = 8192`` I/Q samples. + +-------------------------------------------------------------------- +2. Synthesis Parameters +-------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + :widths: 20 15 55 + + * - Parameter + - RTL Default + - Description + * - ``NM`` + - 8 + - Number of parallel memories/channels captured per write-side clock + (``mr_buffer_et.sv``). Each channel is written into its own BRAM. + * - ``N`` + - 8 + - Address width of each channel's BRAM; depth is ``2**N`` samples. + * - ``B`` + - 16 + - Data width, in bits, of one sample in one channel + (``s_axis_tdata`` is ``NM*B`` bits wide overall; ``m_axis_tdata`` is + ``B`` bits wide, one channel's sample per beat on read-back). + * - ``C_S_AXI_DW`` + - 32 + - AXI4-Lite data width (control-register bus). + * - ``C_S_AXI_AW`` + - 6 + - AXI4-Lite address width. With 16 32-bit registers this must be at + least ``$clog2(4) + $clog2(16) = 6`` bits, which is exactly what the + RTL uses. + * - ``DEBUG`` + - 0 + - When 1, ``s_dbg_probe``/``m_dbg_probe`` (32 bits each) are driven out + for an ILA; when 0 they are tied to zero. + +The RTL defaults above (``NM=8``, ``N=8``, ``B=16``) are not what real +boards use -- e.g. ``qick_tprocv2_111_standard`` overrides ``B=32`` and +``N=10`` (see Section 1) while leaving ``NM`` at its default of 8. Total +capture depth is always ``cfg['maxlen'] = NM * 2**N`` samples (this is +also how the Python driver computes it -- see Section 5). + +-------------------------------------------------------------------- +3. Datapath +-------------------------------------------------------------------- + +3.1 Write side -- ``axis_to_bram_trig`` (one instance per channel) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``mr_buffer.sv`` slices the wide ``s_axis_tdata`` (``NM*B`` bits) into +``NM`` per-channel ``B``-bit slices and instantiates one +``axis_to_bram_trig`` plus one true-dual-port BRAM (``bram_tdp``) per +channel. Each ``axis_to_bram_trig`` (``firmware/ip/mr_buffer_et/src/axis_to_bram_trig.sv``) +runs a 4-state FSM: + +``INIT_ST -> TRIGGER_ST -> CAPTURE_ST -> END_ST`` + +* **INIT_ST**: idle; waits for ``capture_reg=1`` (the synchronized + ``dw_capture_reg``); counters held cleared. +* **TRIGGER_ST**: armed, waiting for a ``trigger`` pulse (the arm can still + be cancelled here by dropping ``capture_reg``). +* **CAPTURE_ST**: accepts AXI4-Stream input (``s_axis_tready`` asserted) + and moves data from a small internal FIFO into the channel's BRAM. + Retires to ``END_ST`` either when the capture window fills (``2**N`` + samples written) or ``capture_reg`` drops (an abort). +* **END_ST**: stops accepting new stream beats but keeps draining whatever + is still queued in the FIFO into BRAM, so the tail of a capture is never + lost when ``capture_reg`` drops mid-stream. Holds ``o_capture_done=1`` + (a level, not a sticky bit) until software de-asserts ``capture_reg`` and + the internal FIFO is empty, at which point it returns to ``INIT_ST``. + +An internal 16-deep synchronous FIFO (``fifo_sync``, first-word-fall-through) +decouples the AXI4-Stream handshake from the BRAM write pipeline; the +module's own header comments state the write-side invariants explicitly: +every beat actually accepted (``tvalid && tready``, not ``tvalid`` alone) +is written to the FIFO exactly once, every word popped from the FIFO while +the window still has room is committed to BRAM (the write pipeline is +driven off ``fifo_rd_en`` itself, so a state transition can't cancel an +in-flight write), and once the window is full further FIFO words are still +popped (and discarded) rather than stalling, so the FSM can still reach +``fifo_empty`` and retire. ``s_axis_tready`` from all ``NM`` channels is +AND-reduced (``mr_buffer.sv``) into the block's single ``s_axis_tready`` +output -- all channels must have room, since they're written from the same +wide input word. + +``o_capture_done`` from each of the ``NM`` per-channel FSMs is AND-reduced +in ``mr_buffer.sv`` into ``o_capture_done``, which crosses into +``s_axi_aclk`` through a 2-stage ``cdc_bit_sync`` and lands in the +AXI4-Lite ``STATUS`` register (register index 2, bit 0 -- see Section 4). + +3.2 Read side -- ``bram_to_axis_nt`` (shared, reads all channels) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +On the read side, all ``NM`` BRAMs' port-B outputs are concatenated into +one wide bus and fed to a single ``bram_to_axis_nt`` instance +(``firmware/ip/mr_buffer_et/src/bram_to_axis_nt.sv``), which walks every +address (0 to ``2**N-1``) and every channel (0 to ``NM-1``) at each +address, serializing the whole window onto the ``B``-bit +``m_axis_tdata``/``m_axis_tvalid``/``m_axis_tlast`` output. Output word +order for one read burst (``TOTAL_WORDS = NM*2**N``): + +:: + + word 0 : ch0 @ addr 0 + word 1 : ch1 @ addr 0 + ... + word NM-1 : ch(NM-1) @ addr 0 + word NM : ch0 @ addr 1 + ... + word NM*2**N - 1 : ch(NM-1) @ addr (2**N - 1) <- tlast here + +FSM: ``INIT_ST -> READ_ST -> WRITE_ST -> ... -> READ_LAST_ST -> +WRITE_LAST_ST -> FIFO_ST -> END_ST -> INIT_ST``, started by ``start_reg`` +(the synchronized ``dr_start_reg``). ``READ_ST``/``WRITE_ST`` alternate, +reading one BRAM address then cycling the channel selector through all +``NM`` channels at that address before advancing to the next address; +``READ_LAST_ST``/``WRITE_LAST_ST`` handle the final address, tagging the +very last channel's word with ``tlast``. Output beats are queued through +another internal FIFO (16 deep, widened by one bit to carry the ``tlast`` +tag alongside the data, so ``tlast`` can never drift out of step with its +beat). + +The module's own header documents a real bug fixed between v1.0 and v1.1 +of this file that's worth knowing about if you ever touch this RTL: v1.0 +retired ``FIFO_ST`` on the FIFO's ``empty`` flag and gated +``m_axis_tvalid`` on the FSM state, but Xilinx's XPM ``empty`` flag +deasserts a cycle or two *after* a write, so the FSM could sample +``empty=1`` while the final words (including the ``tlast`` beat) were +still in flight, strand them, and hang a downstream AXI-DMA waiting for a +``tlast`` that never came. v1.1 fixes this with an exact flight counter +(``fifo_level``, incremented/decremented directly from the write/read +strobes rather than from the XPM status flags) that ``FIFO_ST`` uses to +decide when the burst has truly drained, and by only gating +``m_axis_tvalid`` off in ``INIT_ST`` (never mid-burst). + +3.3 Clock-domain crossings +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Three control signals cross clock domains via ``cdc_gray_sync`` (a 2-stage, +per-bit synchronizer -- despite the name, it does not gray-decode; see +``cdc_gray_sync.sv``, used here with ``N=2``, ``M=1``): + +* ``dw_capture_reg`` (AXI-Lite domain) -> ``s_axis_aclk``. +* ``trigger`` OR'd with the debug force-trigger bit (``debug_reg[0]``) -> + ``s_axis_aclk``. +* ``dr_start_reg`` (AXI-Lite domain) -> ``m_axis_aclk``. + +and ``o_capture_done`` (from ``s_axis_aclk``, the write-side FSMs) crosses +back into ``s_axi_aclk`` via a 2-stage ``cdc_bit_sync`` in +``mr_buffer_et.sv`` before landing in the ``STATUS`` register. + +3.4 Debug forcing +^^^^^^^^^^^^^^^^^ + +The 32-bit ``debug_reg`` (register 15, RW) has two functional bits +(``mr_buffer.sv``): bit 0 ORs a software-forced pulse into the hardware +``trigger`` input before CDC, and bit 1 forces ``s_axis_tready`` high +regardless of the AND-reduced per-channel ready signals +(``s_axis_tready = (&s_axis_tready_i) | s_axis_tready_force``) -- useful +for driving the input stream during bring-up without a real trigger +source or without every channel individually asserting ready. + +-------------------------------------------------------------------- +4. Register Map +-------------------------------------------------------------------- + +The AXI4-Lite interface is a generic 16-register, 32-bit-per-register +slave (``axil_slv.sv``, ``NUM_REGS=16``, ``AXI_DW=32``); with +``C_S_AXI_AW=6`` the register index is address bits ``[5:2]`` (byte +address = register index * 4). Only register 2 is marked read-only in +hardware (``RO_MASK = 16'b0000_0000_0000_0100``, i.e. bit 2); all other +registers are plain read/write and reset to 0 (``mr_buffer_et.sv`` does +not override ``axil_slv``'s default zero ``REG_INIT_VAL``). + +.. list-table:: + :header-rows: 1 + :widths: 15 20 15 50 + + * - Index + - Register + - Width + - Description + * - 0 + - ``dw_capture_reg`` + - 1 bit (RW) + - 1 = arm the writer (capture-enable). Must be de-asserted and + re-asserted to allow a new capture (per the driver's own + docstring comment in ``qick_lib/qick/drivers/readout.py``). + * - 1 + - ``dr_start_reg`` + - 1 bit (RW) + - 1 = start the reader (drain the captured window out on + ``m_axis``). Must be de-asserted and re-asserted to allow a new + transfer. + * - 2 + - ``STATUS`` (``capture_done``) + - 1 bit (RO) + - Bit 0 mirrors ``o_capture_done`` (synchronized into + ``s_axi_aclk``): high once the write-side FSMs have all reached + ``END_ST``. **Not currently read by the Python driver** -- see the + note in Section 5. + * - 3-14 + - reserved + - -- + - Unused; reads as 0. + * - 15 + - ``debug_reg`` + - 32 bits (RW) + - Bit 0: force ``trigger``. Bit 1: force ``s_axis_tready`` high (see + Section 3.4). Remaining bits unused. + +-------------------------------------------------------------------- +5. Python Interface +-------------------------------------------------------------------- + +The block is exposed through ``qick.drivers.readout.MrBufferEt`` +(``bindto`` covers VLNVs ``user.org:user:mr_buffer_et:1.0``/``1.1`` and +``QICK:QICK:mr_buffer_et:1.0``/``1.1`` -- see the version note at the top +of this page). ``QickSoc`` auto-discovers at most one ``MrBufferEt`` +instance that is actually wired to a readout (multiple would raise +``RuntimeError``, see ``qick_lib/qick/qick.py``) and exposes it as +``soc.mr_buf``, plus two convenience methods on ``QickSoc`` itself: + +.. code-block:: python + + from qick import * + + soc = QickSoc() + + # Arm the buffer for readout channel RO_CH (selects the right switch + # input, then toggles capture off/on so a fresh capture always starts + # from a clean state). + soc.arm_mr(ch=RO_CH) + + # Trigger it from a program -- add mr=True to any trigger() call, + # or call it once in initialize() since later triggers are ignored + # until the buffer is re-armed. + prog = QickProgram(soccfg) + prog.declare_readout(ch=RO_CH, freq=FREQ, length=100, gen_ch=GEN_CH) + prog.trigger(mr=True) + prog.end() + prog.config_all(soc) + soc.tproc.start() + + # Read back the captured window: an (n_samples, 2) array of int16, [:,0]=I, [:,1]=Q + iq = soc.get_mr() + +``soc.arm_mr(ch)`` calls ``mr_buf.set_switch()`` (routes the shared +``axis_switch_mr`` to the given readout channel -- or, if the board has no +switch, just asserts that the requested channel is the one hardwired in) +followed by ``mr_buf.disable()``/``mr_buf.enable()`` (toggle +``dw_capture_reg`` 0->1 to arm a fresh capture). ``soc.get_mr(start=None)`` +calls ``mr_buf.transfer(start)``, which sets ``dr_start_reg=1``, DMAs the +whole ``NM*2**N``-sample window into a preallocated buffer +(``self.buff``, a ``pynq.allocate``'d ``np.int16`` array of shape +``2*cfg['maxlen']``) via the traced-out AXI-DMA (``self.dma``), clears +``dr_start_reg``, and returns ``np.copy(self.buff).reshape((-1,2))[start:]``. + +``cfg['maxlen']`` is computed as ``2**N * NM`` from the synthesis +generics read out of the block description (``_init_config``), matching +the ``TOTAL_WORDS`` quantity from Section 3.2. + +.. note:: + + The driver's ``REGISTERS`` dict only defines ``dw_capture_reg`` (index + 0) and ``dr_start_reg`` (index 1) -- it does not read the ``STATUS`` + register (index 2) described in Section 4, so ``capture_done`` is not + currently surfaced to Python; ``transfer()`` relies on the AXI-DMA + S2MM transfer completing (``self.dma.recvchannel.wait()``) rather than + polling hardware capture-done status. + +.. note:: + + ``_init_config`` sets ``cfg['junk_len'] = 8`` if the bound IP type + string contains ``mr_buffer_et:1.0``, else ``0`` -- a workaround for a + firmware bug (fixed in IP version 1.1, per git history) where the first + several samples of a transfer read back as stale/junk data. + ``transfer(start=None)`` defaults ``start`` to this ``junk_len`` and + skips that many samples from the front of the returned array. Note + that the demo notebook (``qick_demos/08_Special_buffers.ipynb``) + describes this as "the first 8 samples are always stale" without the + version conditional -- treat the driver's version-gated + ``cfg['junk_len']`` as the authoritative value for a given board's + bound IP version. + +-------------------------------------------------------------------- +Related Documentation +-------------------------------------------------------------------- + +* :doc:`/avg_buffer` -- the buffer that captures the *decimated* stream + from the same readouts (accumulated and raw-decimated modes); + ``mr_buffer_et`` instead captures the undecimated stream. +* :doc:`/readout_v2` and :doc:`/readout_dynamic` -- the readouts whose + undecimated output (``m0_axis`` on the dynamic readouts) feeds this + block via ``axis_switch_mr``. +* :doc:`/tprocv2_trm` -- the tProcessor trigger port that starts a + capture, via ``prog.trigger(mr=True)``. + +.. note:: + + ``AxisBufferDdrV1`` (``qick.drivers.readout.AxisBufferDdrV1``, RTL + under ``firmware/ip/axis_buffer_ddr_v1/``) is the other DDR4-adjacent + buffer block and is easy to confuse with ``mr_buffer_et``, but the two + are quite different. Per its own driver docstring, ``AxisBufferDdrV1`` + "is fed by the downconverted+decimated data stream coming out of the + readout" -- i.e. the *same* stream that feeds :doc:`/avg_buffer`, not + the undecimated stream ``mr_buffer_et`` sees -- and it streams + continuously into off-chip DDR4 memory (via an AXI memory-mapped port, + ``rstart_reg``/``wstart_reg``/``wnburst_reg`` etc.) rather than a small + on-chip BRAM, giving it a vastly larger (multi-GiB) but still + finite/wraparound capture depth. Its Python surface is + ``soc.arm_ddr4()``/``soc.get_ddr4()`` rather than + ``soc.arm_mr()``/``soc.get_mr()``. diff --git a/docs/papers.rst b/docs/source/papers.rst similarity index 100% rename from docs/papers.rst rename to docs/source/papers.rst diff --git a/docs/quick_start.rst b/docs/source/quick_start.rst similarity index 100% rename from docs/quick_start.rst rename to docs/source/quick_start.rst diff --git a/docs/source/readout.rst b/docs/source/readout.rst new file mode 100644 index 000000000..83dba230d --- /dev/null +++ b/docs/source/readout.rst @@ -0,0 +1,177 @@ +Readout System - QICK Firmware +============================== + +.. contents:: + :local: + :depth: 2 + +Overview +-------- + +The QICK readout system is built around two main IP blocks: + +* **Readout Block** - Digital down-conversion (DDC), filtering, and decimation +* **Average + Buffer Block** - Data accumulation and storage + +The readout process is triggered by a dedicated single-bit ``trig_N_o`` pin +from the tProcessor (one per averaging buffer instance -- see +:ref:`tproc-ports` in :doc:`/firmware` for the full pin model) and can be +configured for raw sample capture or coherent averaging. + +.. figure:: ../../graphics/qsystem-readout.svg + :width: 100% + :align: center + +Readout Block +------------- + +The readout block performs: + +1. **Digital Down-Conversion (DDC)** - Mixes the ADC input with a DDS tone +2. **FIR Filtering** - Anti-aliasing filter +3. **Decimation by 8** - Reduces sample rate for easier processing + +**Key parameters:** + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Parameter + - Description + * - DDS frequency + - Configured via register (not intended for real-time hopping) + * - FIR taps + - Fixed coefficients (compiled into firmware) + * - Decimation factor + - Fixed at 8 + * - Input selection + - Can route raw input, DDS wave, or frequency-shifted signal + +The user can select which signal is sent to the FIR stage using an output selection register. + +Average + Buffer Block +---------------------- + +This block receives the decimated data stream and can: + +* **Store raw samples** - Capture individual samples for analysis +* **Perform coherent averaging** - Accumulate multiple acquisitions + +**Capabilities:** + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Parameter + - Value + * - Raw buffer length + - Board-dependent, ``2**N_BUF`` samples per component (I/Q) -- see + :doc:`/avg_buffer` + * - Accumulated buffer length + - Board-dependent, ``2**N_AVG`` samples per component (I/Q) -- see + :doc:`/avg_buffer` + * - Trigger source + - One dedicated ``trig_N_o`` pin per buffer instance, *not* a bit + within a channel-numbered data word -- see :ref:`tproc-ports` in + :doc:`/firmware` + +The buffer IP that stores/accumulates this data (registers, DMA transfer, +edge-counter mode) is documented separately in :doc:`/avg_buffer`. + +Python Interface +---------------- + +Normal QICK programs do **not** poke the readout/buffer drivers directly. +The workflow, inside a :class:`.QickProgram` (e.g. an +:class:`.AveragerProgramV2` subclass), is: + +1. Declare each readout channel you'll use, once, with + :meth:`.QickProgram.declare_readout` -- this sets the downconversion + frequency/phase/output-select and the readout window length. +2. Fire the ADC capture at the right point in your sequence with + :meth:`.QickProgramV2.trigger` (or the tProc v1 equivalent). +3. After running the program, pull the data back with + :meth:`.AcquireMixin.acquire` (accumulated) or + :meth:`.AcquireMixin.acquire_decimated` (raw waveform) -- see + :doc:`topics/readout_modes` for which one to use. + +.. code-block:: python + + from qick import * + + soc = QickSoc() + + class LoopbackProgram(AveragerProgramV2): + def _initialize(self, cfg): + # readout channel 0: 100 MHz downconversion, 3 us window + self.declare_readout(ch=0, length=3.0, freq=100.0, gen_ch=0) + self.declare_gen(ch=0, nqz=1) + self.add_pulse(ch=0, name="probe", style="const", + freq=100.0, phase=0, gain=0.5, length=3.0) + + def _body(self, cfg): + self.trigger(ros=[0], t=0) # arm readout channel 0 + self.pulse(ch=0, name="probe", t=0) + self.delay_auto(t=1.0) # wait for pulse+readout to finish before looping + + prog = LoopbackProgram(soccfg, reps=1000, final_delay=10.0, cfg={}) + + # Accumulated: one (I, Q) point per rep, averaged + iq_avg = prog.acquire(soc) + + # Decimated: the raw readout waveform (for debugging the window/pulse) + prog2 = LoopbackProgram(soccfg, reps=1, final_delay=10.0, cfg={}) + iq_dec = prog2.acquire_decimated(soc) + +**Low-level driver access:** + +The readout and buffer are still reachable directly, as ``soc.readouts[i]`` +and ``soc.avg_bufs[i]``, for debugging or hand-rolled acquisition outside +the ``acquire()``/``acquire_decimated()`` flow -- see :doc:`/avg_buffer`'s +Python Interface section for the buffer-level ``config_avg``/ +``transfer_avg``/``config_buf``/``transfer_buf`` calls this normally sits on +top of. :meth:`.AbsReadout.set_all`/``set_all_int`` on the readout driver +itself are explicitly for debugging only -- the recommended way to configure +a readout's frequency/phase/output-select is ``declare_readout()``. + +Hardware Considerations +----------------------- + +**Clock frequencies:** + +- ADC sampling rate: ``soc.fs_adc`` (typically 3072 MHz) +- After decimation by 8: effective rate = ``soc.fs_adc / 8`` + +**Buffer sizes:** + +- Raw mode: up to ``soc.cfg['readouts'][i]['buf_maxlen']`` I/Q pairs (1024 on + the reference board, i.e. 2k total samples) +- Average mode: up to ``soc.cfg['readouts'][i]['avg_maxlen']`` I/Q pairs + (16384 on the reference board, i.e. 32k total) -- read these from your own + board's config rather than assuming a number, see :doc:`/avg_buffer`. + +**Example: Calculating acquisition time** + +.. code-block:: python + + n_samples = 1024 + decimation = 8 + adc_rate = soc.fs_adc # Hz + sample_period = 1 / (adc_rate / decimation) # seconds per decimated sample + acquisition_time = n_samples * sample_period + print(f"Acquisition takes {acquisition_time * 1e6:.2f} us") + +Related Documentation +--------------------- + +* :doc:`/avg_buffer` - the averaged/raw buffer IP downstream of this readout +* :doc:`/readout_pfb` - the polyphase-filter-bank multi-channel readout + variant (``axis_pfb_readout_v2``/``v3``/``v4``), which channelizes into + several simultaneous demod outputs instead of one tunable frequency +* :doc:`topics/readout_modes` - ``acquire()`` vs. ``acquire_decimated()`` +* :doc:`/tprocv2_trm` - tProcessor v2 for triggering and sequencing +* :doc:`/firmware` - Firmware overview and channel assignments +* :doc:`topics/timing` - Timing considerations for readout +* :doc:`topics/freq_matching` - Frequency matching between generators and readouts diff --git a/docs/source/readout_dynamic.rst b/docs/source/readout_dynamic.rst new file mode 100644 index 000000000..353986d52 --- /dev/null +++ b/docs/source/readout_dynamic.rst @@ -0,0 +1,499 @@ +======================================================================== +Dynamic Readouts (axis_readout_v3 / axis_dyn_readout_v1) - QICK Firmware +======================================================================== + +.. contents:: + :local: + :depth: 2 + +**axis_readout_v3** and **axis_dyn_readout_v1** are the *dynamic* counterparts +of :doc:`/readout_v2`: digital down-converter (DDC) IP blocks that sit +between the RFDC's ADC output and :doc:`/avg_buffer`, but whose +frequency/phase/output-selection/length are set **by the tProcessor, in real +time, once per shot**, instead of being written ahead of time as PYNQ +registers from software. Both modules live under ``firmware/ip/`` (in +``axis_readout_v3/`` and ``axis_dyn_readout_v1/`` respectively) and are +exposed to Python through ``qick.drivers.readout.AxisReadoutV3`` and +``AxisDynReadoutV1``. + +They are covered together on one page because they share the same control +architecture (a nearly-identical FSM, ``ctrl.sv``/``ctrl_dyn_ro_v1.sv``, and +the same tProc-driven configuration mechanism) and the same Python-driver +pattern (``AbsDynReadout``); the numeric parameters of their datapaths +(samples/clock, decimation ratio, rounding) differ, and those differences are +called out explicitly below. + +-------------------------------------------------------------------- +1. General Description +-------------------------------------------------------------------- + +Both blocks perform the same three-stage job as ``axis_readout_v2`` +(down-convert with an on-chip DDS, FIR low-pass filter, decimate), but they +have **no AXI-Lite control interface at all** -- neither module's top-level +port list (``axis_readout_v3.v``, ``axis_dyn_readout_v1.v``) includes an +``S_AXI``/register bus. Instead, each block exposes an extra AXI-Stream slave +port, ``s0_axis``, driven directly by a tProcessor output port. The +tProcessor pushes one 88-bit configuration word per ``s0_axis`` transaction; +the block's control FSM decodes that word into DDS frequency/phase and +readout-length/output-select settings and applies them immediately. This is +the hardware side of what :meth:`.QickProgram.declare_readout` calls a +readout "controlled by tProc" (see :ref:`readout-dyn-python` below) -- +config­uration happens per-shot, at run time, as part of the tProc program +itself, rather than once via a PYNQ register write before the program starts. + +* **axis_readout_v3** -- the dynamic counterpart of ``axis_readout_v2``'s + datapath: 4 real ADC samples/clock in, FIR decimation by 4, 1 complex + sample/clock out (``m_axis``, the only output). +* **axis_dyn_readout_v1** -- a newer, wider block: 8 real ADC samples/clock + in (``N_DDS=8``), FIR decimation by 8. Unlike v3, it exposes **two** + outputs: ``m0_axis``, the down-converted-but-not-yet-decimated stream (8 + complex samples/clock, still subject to the output-selection mux), and + ``m1_axis``, the final decimated stream (1 complex sample/clock) that feeds + :doc:`/avg_buffer`. + +Both are single-tone readouts (one DDS-driven downconversion frequency at a +time per channel) -- like ``axis_readout_v2`` and unlike the PFB-based +readouts, they do not channelize multiple simultaneous tones. + +-------------------------------------------------------------------- +2. Synthesis Parameters +-------------------------------------------------------------------- + +.. list-table:: axis_readout_v3 vs. axis_dyn_readout_v1 -- key parameters + :header-rows: 1 + :widths: 30 20 20 30 + + * - Parameter + - axis_readout_v3 + - axis_dyn_readout_v1 + - Notes + * - Input samples/clock (``N``/``N_DDS``) + - 4 + - 8 + - Parallel real ADC lanes into the down-conversion multiplier; also the + number of DDS instances (``dds_0``/``dds_compiler_0``). + * - FIR decimation ratio + - 4 + - 8 + - Xilinx FIR Compiler 7.2, ``Filter_Type=Decimation``. Exposed to Python + as ``DOWNSAMPLING`` on the driver class (``4`` / ``8``). + * - FIR coefficients + - 107 taps (``fir_0/fir.coe``) + - 120 taps (``fir.coe``) + - Symmetric low-pass, fixed/compiled into the bitstream (not + runtime-loadable). + * - FIR coefficient/data width + - 16 bits + - 16 bits + - ``Coefficient_Width``/``Data_Width`` on both FIR IPs. + * - FIR output width (per I/Q component) + - 18 bits + - 16 bits + - See :ref:`readout-dyn-rounding` for how each top level turns this into + the final 16-bit I/Q. + * - DDS phase/output width + - 32-bit phase, 16-bit output + - 32-bit phase, 16-bit output + - Same on both (``dds_0``/``dds_compiler_0``, ``Phase_Width=32``, + ``Output_Width=16``). + * - DDS latency + - 10 cycles + - 8 cycles + - IP-configured pipeline latency of the DDS compiler core. + * - Config-descriptor FIFO depth + - 8 entries + - 8 entries + - ``fifo #(.B(88), .N(8))`` in both top levels -- up to 8 pending + ``s0_axis`` configuration words can be queued. + * - Config descriptor width + - 88 bits + - 88 bits + - See :ref:`readout-dyn-descriptor`. + +-------------------------------------------------------------------- +3. Datapath +-------------------------------------------------------------------- + +3.1 axis_readout_v3 +^^^^^^^^^^^^^^^^^^^^ + +``axis_readout_v3.v`` instantiates a single 88-bit-wide, 8-deep FIFO (fed by +``s0_axis``) and one ``down_conversion_fir`` block: + +1. **down_conversion** (``down_conversion.sv``) -- reads one descriptor at a + time out of the FIFO via an internal ``ctrl`` FSM (see + :ref:`readout-dyn-fsm`), drives 4 parallel ``dds_0`` DDS cores from it, + and complex-multiplies each of the 4 real ADC samples/clock + (``s1_axis_tdata``) against its DDS output. Latency-matched shift + registers (``latency_reg``) keep the raw-input and DDS-only paths aligned + in time with the product path so all three can be muxed together. +2. **down_conversion_fir** (``down_conversion_fir.sv``) -- feeds the 4 + parallel 32-bit (16+16 I/Q) product-domain samples/clock into ``fir_0`` + (decimation by 4), producing one complex sample/clock on ``m_axis``. + +``down_conversion_fir.sv`` documents the block's overall latency in comments: +16 cycles through ``down_conversion``, 114 more through the FIR. + +3.2 axis_dyn_readout_v1 +^^^^^^^^^^^^^^^^^^^^^^^^ + +``axis_dyn_readout_v1.v`` wraps a ``readout_top`` module, which instantiates +the same FIFO (88 bits x 8 deep) and a ``down_conversion_fir`` block built +from 8-lane versions of the same pieces: + +1. **down_conversion** (``down_conversion.v``) -- same structure as v3's + (shared ``ctrl_dyn_ro_v1`` FSM, per-lane DDS + complex multiply), but with + ``N_DDS=8`` lanes and no latency-matching shift registers on the + DDS/input mux paths (the mux paths are only delay-matched by fixed + pipeline register counts, not by a parametrized ``latency_reg`` block as + in v3). This stage's output is exposed directly as ``m0_axis`` (8 complex + samples/clock, pre-filter/pre-decimation, still passed through the + output-selection mux). +2. **fir_compiler_0**, wrapped by ``down_conversion_fir.v`` -- an 8x + decimation, multi-rate FIR core (``Number_Paths=2``, one path per I/Q + component) that consumes ``m0_axis`` directly and produces the final + 1-complex-sample/clock stream on ``m1_axis``. + +.. _readout-dyn-fsm: + +3.3 Shared control FSM (``ctrl.sv`` / ``ctrl_dyn_ro_v1.sv``) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Both blocks' control logic is built from what is essentially the same +two-state FSM (``READ_ST``/``CNT_ST``, one-hot encoded): + +* In ``READ_ST``, the FSM asserts ``fifo_rd_en`` and, once a descriptor is + available (``~fifo_empty``) or the previously-loaded descriptor's + ``mode`` bit is 1 ("periodic"), latches it and moves to ``CNT_ST``. +* In ``CNT_ST`` it holds that descriptor's frequency/phase/output-select + settings for ``nsamp-2`` clock cycles (counted by a free-running counter, + ``cnt``), then returns to ``READ_ST`` to look for (or wait for) the next + descriptor. + +From the latched ``freq``/``phase`` fields the FSM computes, per DDS lane +``i``, a phase-coherent phase word ``phase_v1[i] = i*pinc + running_phase``, +where the running phase accumulates ``pinc*N`` per clock (``N`` = 4 or 8, the +number of lanes) and resets to the descriptor's ``phase`` field whenever +``sync`` (a new descriptor being loaded) coincides with the descriptor's +``phrst`` bit being set. This is what makes the DDS phase-coherent across +consecutive tProc-issued descriptors except where the program explicitly +requests a phase reset. + +**One difference between the two FSMs**: ``ctrl.sv`` (axis_readout_v3) also +computes an output-enable signal ``en`` (asserted once a descriptor has been +loaded and the FIFO isn't empty, deasserted in periodic mode's gaps). However, +tracing it through ``down_conversion.sv`` shows this signal is latency-matched +(``en_latency_reg_i``) but **never wired to anything that gates the +datapath** -- ``down_conversion.sv`` computes its outputs unconditionally +(the source comment there reads *"Always on output (not using en like in +signal_gen_v6)"*), and ``m_axis_tvalid`` is hardwired to 1. So in the current +axis_readout_v3 RTL, ``en`` is a vestigial signal with no observable effect. +Consistent with that, ``ctrl_dyn_ro_v1.sv`` (used by axis_dyn_readout_v1) has +the entire ``en``/output-enable logic commented out and does not produce an +``en`` port at all -- one confirmed, RTL-verified difference between the two +control modules, not just a naming variant. + +.. _readout-dyn-descriptor: + +3.4 Configuration descriptor (the ``s0_axis`` word) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Both ``ctrl.sv`` and ``ctrl_dyn_ro_v1.sv`` carry an identical header comment +describing the 88-bit ``s0_axis_tdata``/FIFO word layout: + +.. list-table:: Configuration descriptor (``s0_axis_tdata``, 88 bits) + :header-rows: 1 + :widths: 20 15 65 + + * - Field + - Bits + - Description + * - (reserved) + - ``[87:84]`` + - Unused ("xxxx" in the source comment). + * - ``phrst`` + - ``[83]`` + - 1: reset the phase-coherent DDS accumulator when this descriptor is + loaded. 0: keep accumulating phase from the previous descriptor. + * - ``mode`` + - ``[82]`` + - 0: hold this descriptor's settings for ``nsamp`` cycles, then load the + next one. 1: periodic -- keep re-loading (repeating) this descriptor + without waiting for a new one to arrive on ``s0_axis``. + * - ``outsel`` + - ``[81:80]`` + - Output source select (see :ref:`readout-dyn-outsel`). + * - ``nsamp`` + - ``[79:64]`` + - Number of clock cycles (not decimated output samples) this + descriptor's settings are held for, in one-shot mode. + * - ``phase`` + - ``[63:32]`` + - DDS phase offset. + * - ``freq`` + - ``[31:0]`` + - DDS tuning word (downconversion frequency). + +This is the same freq/phase/nsamp/outsel/mode field set as +``axis_readout_v2``'s register-composed descriptor (see +:doc:`/readout_v2`'s 83-bit FIFO word), plus one extra field, ``phrst``, that +``axis_readout_v2`` does not have -- and it arrives as a single AXI-Stream +push from the tProcessor rather than being assembled from five separate +PYNQ registers and committed with a ``WE_REG`` pulse. + +.. _readout-dyn-outsel: + +3.5 Output source selection +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Both blocks' output multiplexers (``dout_mux`` in ``down_conversion.sv`` / +``down_conversion.v``) use the same encoding for the 2-bit ``outsel`` field: + +.. list-table:: + :header-rows: 1 + :widths: 15 25 60 + + * - ``outsel`` + - Value + - Description + * - 0 + - product + - The demodulated signal: ADC input x DDS (the normal downconverted + output). + * - 1 + - dds + - The raw local-oscillator (DDS) tone, delay-matched -- for calibration + or debugging. + * - 2 + - input + - Bypass: the raw real ADC sample (delay-matched), with the imaginary + part forced to zero. + * - 3 + - zero + - Always outputs zero. + +This matches the ``outsel`` encoding used by :meth:`.QickProgram.cfg2reg` for +tProc-v2 pulses/readout configs (``"product"``/``"dds"``/``"input"``/``"zero"`` +-> 0/1/2/3) -- the same field format is shared between signal generators and +these dynamic readouts. + +.. _readout-dyn-rounding: + +3.6 Rounding and the I/Q DC offset +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The two blocks round their internal fixed-point products differently, and +this shows up directly in the Python driver's ``IQ_OFFSET`` constant +(``AbsReadout.IQ_OFFSET``, used by :meth:`.AcquireMixin` for offset +correction): + +* **axis_readout_v3** (``down_conversion.sv``): the complex-multiply result + is truncated with a plain bit-slice + (``prod_y_real_round[i] = prod_y_real[i][30 -: 16]``, no rounding + correction added), and the FIR's own output rounding mode is + ``Symmetric_Rounding_to_Zero`` (18-bit output). The top level + (``down_conversion_fir.sv``) then takes bits ``[16:1]`` of each 18-bit + FIR output component to form the final 16-bit I/Q. This truncation-based + chain is why the Python driver sets ``IQ_OFFSET = -0.5`` for + ``AxisReadoutV3``. +* **axis_dyn_readout_v1** (``down_conversion.v``): the complex-multiply + explicitly adds a rounding constant before truncating + (``py_round_real[i] = py_full_real_r[i] + RND_0P5`` where + ``RND_0P5 = 2**15``, then keeps bits ``[31:16]``), and the FIR core's + output width is configured to 16 bits directly (no further truncation at + the top level -- ``m1_axis_tdata_o`` is wired straight from + ``fir_compiler_0``'s output). This explicit rounding is consistent with + the Python driver's ``IQ_OFFSET = 0.0`` for ``AxisDynReadoutV1``. + +-------------------------------------------------------------------- +4. Why There's No Register Map +-------------------------------------------------------------------- + +Unlike ``axis_readout_v2`` (:doc:`/readout_v2`), neither ``axis_readout_v3`` +nor ``axis_dyn_readout_v1`` has an AXI-Lite slave port in its top-level +Verilog -- there is no ``FREQ_REG``/``PHASE_REG``/``NSAMP_REG``/ +``OUTSEL_REG``/``MODE_REG``/``WE_REG`` set to document, and no register map +section to write for this page. The blocks' only I/O is AXI-Stream: + +.. list-table:: axis_readout_v3 top-level ports + :header-rows: 1 + :widths: 20 15 15 50 + + * - Port + - Direction + - Width + - Description + * - ``s0_axis`` + - slave + - 88 bits + - Configuration descriptors, pushed by the tProcessor (see + :ref:`readout-dyn-descriptor`). Backpressured by the 8-entry FIFO + (``s0_axis_tready = ~fifo_full``). + * - ``s1_axis`` + - slave + - 4x16 bits + - ADC input, 4 real samples/clock. + * - ``m_axis`` + - master + - 32 bits + - Decimated complex (I, Q) output, 1 sample/clock, to + :doc:`/avg_buffer`. + +.. list-table:: axis_dyn_readout_v1 top-level ports + :header-rows: 1 + :widths: 20 15 15 50 + + * - Port + - Direction + - Width + - Description + * - ``s0_axis`` + - slave + - 88 bits + - Configuration descriptors, pushed by the tProcessor. + * - ``s1_axis`` + - slave + - 8x16 bits + - ADC input, 8 real samples/clock. + * - ``m0_axis`` + - master + - 8x32 bits + - Down-converted output, before FIR/decimation, 8 complex samples/clock. + * - ``m1_axis`` + - master + - 32 bits + - Decimated complex (I, Q) output, 1 sample/clock, to + :doc:`/avg_buffer`. + +Because there is no register interface, there is also no PYNQ overlay driver +in the usual sense -- see :ref:`readout-dyn-python`. + +.. _readout-dyn-python: + +-------------------------------------------------------------------- +5. Python Interface +-------------------------------------------------------------------- + +5.1 No PYNQ driver: ``AbsDynReadout`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Every other readout driver in ``qick.drivers.readout`` +(``AxisReadoutV2``, ``AxisPFBReadoutV2/V3/V4``) inherits from ``SocIP``, +which itself inherits from PYNQ's ``DefaultIP`` and is matched to firmware +blocks by IP-registry ``bindto`` strings (e.g. +``bindto = ['user.org:user:axis_readout_v2:1.0', ...]``) when +``Overlay.load()`` scans the bitstream. That mechanism only works for blocks +that expose AXI-Lite registers. + +``AxisReadoutV3`` and ``AxisDynReadoutV1`` instead inherit from +``AbsDynReadout(AbsReadout, DummyIP)`` -- neither class defines a +``bindto``, so PYNQ's overlay loader never instantiates them automatically. +``DummyIP`` (``qick.ip.DummyIP``) exists specifically for "firmware IP blocks +without register access" -- it just swallows the constructor's +``description`` argument so the class can still fit into ``QickIP``'s +``__init__`` chain. As the source comments in both +``AbsDynReadout``/``AxisReadoutV3``/``AxisDynReadoutV1`` put it: *"This isn't +a PYNQ driver, since the block has no registers for PYNQ control. We still +need this class to represent the block and its connectivity."* + +Because these objects never get created by the overlay loader, something +else has to create them. That happens in +``AxisAvgBuffer.configure_connections()`` (``qick.drivers.readout``): when an +``axis_avg_buffer`` traces its upstream ``s_axis`` connection back to an +``axis_readout_v3`` or ``axis_dyn_readout_v1`` block, it manually constructs +the matching ``AxisReadoutV3``/``AxisDynReadoutV1`` instance and calls its +``configure_connections()`` -- the comment there reads *"the dynamic readout +blocks have no registers, so they don't get PYNQ drivers, so we initialize +them here."* ``AbsDynReadout.configure_connections()`` also traces the +block's ``s0_axis`` connection back through the tProcessor (or an +intervening ``axis_tmux_v1`` time-multiplexer) to determine which tProc +output port (``tproc_ctrl``, and optionally ``tmux_ch``) drives this +readout's configuration -- this is what lets software later target the right +tProc port when it sends a configuration. + +5.2 ``declare_readout()``: static vs. dynamic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:meth:`.QickProgram.declare_readout` (``qick.qick_asm``) is where this +distinction surfaces at the program-authoring level. It looks at whether the +readout's config dict has a ``tproc_ctrl`` entry (set by +``AbsDynReadout.configure_connections()`` above, absent for +``axis_readout_v2``/PFB readouts): + +.. code-block:: python + + if 'tproc_ctrl' not in ro_cfg: # readout is controlled by PYNQ + if freq is None: + raise RuntimeError("readout %d is static (PYNQ-configured) - " + "frequency must be set in declaration"%(ch)) + cfg['freq'] = freq + cfg['gen_ch'] = gen_ch + cfg['ro_config'] = self.soccfg.calc_ro_regs(ro_cfg, phase, sel) + else: # readout is controlled by tProc + if phase!=0 or sel!='product' or freq is not None or gen_ch is not None: + raise RuntimeError("readout %d is dynamic (tProc-configured) - " + "freq/phase/sel parameters are set using tProc " + "instructions, not in declaration"%(ch)) + +For a dynamic readout, ``declare_readout()`` only reserves the channel +(readout length, edge-counting, weights) and deliberately *refuses* to accept +``freq``/``phase``/``sel``/``gen_ch`` -- those are set later, per-shot, by +tProc instructions, not once at declaration time. + +5.3 Setting frequency/phase/outsel from a tProc v2 program +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +On tProc v2 (``qick.asm_v2.QickProgramV2``), the program builds one +``ReadoutManager`` per dynamic readout channel +(``self._ro_mgrs = [ReadoutManager(self, iCh) if 'tproc_ctrl' in ch else None +...]``). Two program methods drive it: + +* :meth:`.QickProgramV2.add_readoutconfig` (``ch``, ``name``, ``freq``, + ``phase``, ``outsel``, ``phrst``, ...) computes the register values (DDS + frequency/phase words, and a packed ``outsel``/``mode``/``phrst`` + configuration word via ``cfg2reg``) and stores them as a named "pulse" in + the program. +* :meth:`.QickProgramV2.send_readoutconfig` (``ch``, ``name``, ``t``) emits + the instructions (``ConfigReadout``) that push that pre-computed word to + the readout's ``tproc_ctrl`` port at time ``t``, using the same + ``WPORT_WR`` wave-memory-write mechanism used to schedule signal-generator + pulses (see :doc:`/sg_v6`'s tProc-sequencing section). This is the + run-time source of the ``s0_axis`` descriptor word described in + :ref:`readout-dyn-descriptor`. + +.. code-block:: python + :caption: Configuring a dynamic readout's frequency from a tProc v2 program + + from qick import * + + soc = QickSoc() + prog = QickProgramV2(soc) + + ro_ch = 0 + prog.declare_readout(ch=ro_ch, length=1.0) # no freq/phase/sel here + + # Define the readout config once, up front. + prog.add_readoutconfig(ch=ro_ch, name="myro", freq=100.0, phase=0, outsel="product") + + # ... later, inside the timed part of the program ... + prog.send_readoutconfig(ch=ro_ch, name="myro", t=0) # push freq/phase/outsel to the readout + prog.trigger(ros=[ro_ch], t=0.5) # arm the buffer to capture + +tProc v1 programs (``qick.asm_v1``) have an equivalent ``ReadoutManager`` and +follow the same two-step (build descriptor, then instruction-schedule it) +pattern; the descriptor format on the wire is identical since it's produced +by the same firmware control FSM. + +Related Documentation +---------------------- + +* :doc:`/readout` -- readout system overview. +* :doc:`/readout_v2` -- the static, PYNQ-register-configured readout these + blocks are the dynamic counterpart of. +* :doc:`/avg_buffer` -- the buffer downstream of ``m_axis``/``m1_axis``. +* :doc:`/tprocv2_trm` -- tProcessor instruction reference, including + ``WPORT_WR`` and the timing model used by ``send_readoutconfig()``. +* :doc:`/sg_v6` -- the signal-generator counterpart of tProc-scheduled, + ``WPORT_WR``-driven configuration. +* :doc:`topics/freq_matching` -- keeping generator and readout frequencies in + sync. diff --git a/docs/source/readout_pfb.rst b/docs/source/readout_pfb.rst new file mode 100644 index 000000000..a2ead63b2 --- /dev/null +++ b/docs/source/readout_pfb.rst @@ -0,0 +1,455 @@ +=============================================================================== +PFB Readouts (axis_pfb_readout_v2 / v3 / v4) - QICK Firmware +=============================================================================== + +.. contents:: + :local: + :depth: 2 + +**axis_pfb_readout_v2**, **axis_pfb_readout_v3**, and **axis_pfb_readout_v4** +are QICK's polyphase-filter-bank (PFB) readouts: unlike every other readout +documented so far (:doc:`/readout_v2`, :doc:`/readout_dynamic`), a PFB readout +channelizes its ADC input into many fixed-frequency slices of the band *in +hardware*, then lets software/tProc pick which slice(s) to route to its +output port(s) and fine-tune each with its own DDS. One PFB readout instance +therefore behaves like several single-tone readouts operating simultaneously +on disjoint (or shared) parts of the spectrum, rather than one tunable +downconverter. All three modules live under ``firmware/ip/`` -- +``axis_pfb_readout_v2/``, ``axis_pfb_readout_v3/``, ``axis_pfb_readout_v4/`` +-- and are exposed to Python through ``qick.drivers.readout.AbsPFBReadout`` +and its ``AxisPFBReadoutV2``/``V3``/``V4`` subclasses. + +.. note:: + Like most of the cores in this doc set, this is **legacy RTL that has not + been ported to the newer fusesoc build system** -- it exists only in the + ``firmware/ip/`` tree, not under a fusesoc core description. That does not + make it dead code: it is real, currently-shipping firmware. The flagship + ZCU216 "tpv2_std" board design (``firmware/Top/216/tpv2_std/bd_2023-1.tcl``, + tracked on branch ``feature/114-integrate-hog-fusesoc``, since it predates + this branch's docs-only history) instantiates one **axis_pfb_readout_v4** + alongside two ``axis_dyn_readout_v1`` (:doc:`/readout_dynamic`) -- see + :ref:`readout-pfb-zcu216` below. + +.. _readout-pfb-general: + +-------------------------------------------------------------------- +1. General Description +-------------------------------------------------------------------- + +All three versions share the same overall pipeline: + +1. **Polyphase filter bank + FFT** -- a bank of parallel FIR filters + (``firs.sv``/``firs``) followed by an FFT splits the input band into N + equally-spaced, overlapping channels, each centered on a different fixed + frequency (an integer multiple of ``fs/N``, where ``fs`` is the ADC sample + rate seen by the PFB). This stage is a fixed, compiled-in channelizer -- + its channel count and spacing are synthesis-time constants, not runtime + registers. +2. **Per-channel or per-output DDS mixing** -- a second, small, *programmable* + DDS fine-tunes each selected channel by up to +/- half a channel width, so + the final demodulation frequency is (fixed PFB channel center) + (DDS + offset), rather than only landing on one of the N coarse PFB bins. +3. **Output routing/selection** -- a subset of the N PFB channels (up to + NOUT of them) is routed to the block's NOUT physical AXI-Stream output + ports, which is what actually gets built (see :ref:`readout-pfb-zcu216`) + -- each output port typically feeds its own :doc:`/avg_buffer` instance + downstream, one PFB readout thus driving multiple avg_buffers. + +Where the three versions differ is **N** (PFB channel count), **NOUT** +(selectable/routed output count), and **whether the fine-tuning DDS sits +before or after output selection** -- all verified directly from RTL below, +not inferred from naming. + +.. list-table:: axis_pfb_readout_v2 / v3 / v4 -- top-level comparison + :header-rows: 1 + :widths: 22 20 20 38 + + * - + - v2 + - v3 + - v4 + * - PFB channels (N) + - 8 (``ssrfft_8x8``, ``NFFT=2*L`` with ``L=4``) + - 64 (``pfb_top``/``pfb_readout`` default parameter ``N=64``, + ``ssrfft_8x64``) + - 64 (same ``pfb_readout``/``pfb`` core as v3, unchanged) + * - Selectable outputs (NOUT) + - 4 (``m0``-``m3``) + - 4 (``m0``-``m3``, ``localparam NOUT = 4`` in ``pfb_top.sv``) + - 8 (``m0``-``m7``, ``localparam NOUT = 8`` in ``pfb_top.sv``) + * - DDS placement + - Per PFB channel (all 8 channels always have a live DDS mixer; + ``DDS_ON_OUTPUT = False`` in the driver) + - Per output (4 independent, phase-coherent DDS blocks, one per + selected output; ``DDS_ON_OUTPUT = True``) + - Per output (8 independent DDS blocks, same structure as v3, just + doubled) + * - Output-channel selection + - ``pfb_mux.sv``: a 3-bit ``CH[0-3]SEL_REG`` per output picks 1 of the 8 + already-DDS-mixed channels + - ``pfb_chsel.sv`` (one instance per output, inside ``pfb_top``): a + 16-bit ``ID[0-3]_REG`` (packet + index into the 64-channel TDM + stream) picks which raw PFB channel feeds that output's DDS + - Same ``pfb_chsel.sv`` mechanism as v3, with 8 instances (``ID[0-7]_REG``) + * - AXI-Lite address width + - 6 bits (``s_axi_awaddr[5:0]``, 13 registers) + - 6 bits (``s_axi_awaddr[5:0]``, 12 registers) + - 8 bits (``s_axi_awaddr[7:0]``, 24 registers -- widened because NOUT + doubled) + +-------------------------------------------------------------------- +2. axis_pfb_readout_v2 +-------------------------------------------------------------------- + +2.1 Datapath +^^^^^^^^^^^^ + +``axis_pfb_readout_v2.v`` instantiates a single block, ``pfb_dds_mux`` +(``pfb_dds_mux.sv``), which chains three sub-blocks: + +1. **pfb** (``pfb.sv``) -- ``firs`` (the polyphase FIR bank, ``L=4`` input + lanes) feeds an ``ssrfft_8x8`` core (``NFFT=SSR=2*L=8``, ``B=16``), which + is then run through ``pimod`` (a "pi modulation" / spectral-reordering + stage). Output is 8 interleaved 32-bit (16-bit I + 16-bit Q) lanes on one + 256-bit-wide AXI-Stream word (``tdata_pfb``) -- **8 fixed PFB channels**, + each centered on ``i * fs/16`` for channel ``i`` (the ``ssrfft_8x8`` + parameterization: 8-point FFT over the PFB's overlapped, 50%-overlap + 50%-decimated stream). +2. **ddsprod_v** (``ddsprod_v.sv``) -- instantiates 8 ``ddsprod`` blocks + (``ddsprod.sv``), one per PFB channel, **always active regardless of + which outputs are actually used**. Each ``ddsprod`` complex-multiplies its + channel's PFB output against a per-channel programmable DDS + (``dds_0``/``FREQ[0-7]_REG``), and its output mux (shared 2-bit + ``OUTSEL_REG`` across all 8 channels) picks between the demodulated + product, the raw (delay-matched) PFB channel input, or the raw DDS tone -- + the same product/input/dds encoding pattern used by the single-tone + readouts (:doc:`/readout_v2`). +3. **pfb_mux** (``pfb_mux.sv``) -- a pure combinational 8-to-1 mux, replicated + 4 times (one per output). Each output's 3-bit ``CH[0-3]SEL_REG`` selects + which of the 8 already-DDS-mixed channels appears on that output + (``m0``-``m3``). + +Because the DDS sits *before* the output mux (per-channel, not per-output), +v2's 4 outputs can only ever carry (a subset of) the 8 channel-DDS results +computed once, shared if two outputs pick the same channel -- there is no way +to independently re-tune the same PFB channel differently on two outputs +simultaneously. + +2.2 Register Map +^^^^^^^^^^^^^^^^^ + +Register offsets below are as wired in ``axi_slv.vhd`` (``slv_reg0`` +.. ``slv_reg12``) and match ``AxisPFBReadoutV2._init_config()``'s +``REGISTERS`` dict in ``qick_lib/qick/drivers/readout.py`` exactly. + +.. list-table:: + :header-rows: 1 + :widths: 22 12 66 + + * - Register + - Width + - Description + * - ``FREQ[0-7]_REG`` + - 32 bits each + - Per-PFB-channel DDS tuning word (one per of the 8 fixed channels, + *not* per output). + * - ``OUTSEL_REG`` + - 2 bits + - Shared by all 8 channel DDS muxes. 0: product (demodulated). 1: input + (bypass, raw PFB channel). 2: dds (raw local-oscillator tone). + * - ``CH0SEL_REG`` .. ``CH3SEL_REG`` + - 3 bits each + - Maps output port N (0-3) to one of the 8 DDS-mixed PFB channels + (0-7). + +-------------------------------------------------------------------- +3. axis_pfb_readout_v3 +-------------------------------------------------------------------- + +3.1 Datapath +^^^^^^^^^^^^ + +``axis_pfb_readout_v3.v`` instantiates ``pfb_readout`` (``pfb_readout.v``, +parameterized ``N=64`` channels, ``L=4`` input lanes), which chains: + +1. **pfb_top** (``pfb_top.sv``) -- instantiates the shared ``pfb`` channelizer + core (50%-overlap PFB into an ``ssrfft_8x64``-based 64-point FFT -- + channel ``i`` centered at ``i * fs/64``), whose 64-channel output stream is + time-division-multiplexed across ``L=8`` parallel lanes (``2*L`` from the + overlap structure), i.e. 8 channels appear per clock, taking 64/8 = 8 + clocks ("packets") to cycle through all 64 channels. ``pfb_top`` + instantiates **NOUT = 4** ``pfb_chsel`` blocks in a ``generate`` loop, one + per output -- each is a TDM channel-extractor: it watches the 8-lane + stream for its configured ``(packet, index)`` pair (from that output's + ``ID[0-3]_REG``) and latches the matching 32-bit (I,Q) sample onto its + output. Unlike v2, **no DDS mixing happens at this stage** -- ``pfb_top`` + only selects a raw PFB channel per output; it has no ``FREQ``/``PINC`` + registers of its own. +2. **ddsprod_v** (a *different*, 4-output-specific ``ddsprod_v.sv`` from + v2's 8-channel one) -- instantiates 4 independent ``ddsprod`` blocks, one + per output, **after** channel selection. Each output gets its own + phase-coherent DDS (``PINC[0-3]_REG``/``POFF[0-3]_REG``) applied to + whichever raw PFB channel that output's ``pfb_chsel`` picked. Because the + DDS is per-output rather than per-channel, the *same* PFB channel can be + routed to two different outputs and independently fine-tuned/phased on + each -- the opposite tradeoff from v2. + +v3 has **no ``OUTSEL_REG``**/output-mode-selection mux at all (confirmed: +``ddsprod.sv`` in v3/v4 has no ``OUTSEL_REG`` port, unlike v2's; the Python +driver sets ``HAS_OUTSEL = False`` for ``AxisPFBReadoutV3``) -- each output +always carries the demodulated product, nothing else. + +3.2 Register Map +^^^^^^^^^^^^^^^^^ + +Confirmed against ``axi_slv.vhd`` (``slv_reg0``..``slv_reg11``, 12 registers, +6-bit address bus) and ``AxisPFBReadoutV3._init_config()``, which builds the +same offsets programmatically (``id%d_reg`` at 0-3, then ``freq%d_reg``/ +``phase%d_reg`` pairs at 4/5, 6/7, 8/9, 10/11). Note the RTL register names +(``ID``/``PINC``/``POFF``) differ from the Python driver's friendlier names +(``id``/``freq``/``phase``) for the same bits -- ``PINC`` = phase increment +(frequency tuning word), ``POFF`` = phase offset. + +.. list-table:: + :header-rows: 1 + :widths: 22 12 66 + + * - Register (RTL / driver name) + - Width + - Description + * - ``ID[0-3]_REG`` / ``id[0-3]_reg`` + - 16 bits + - Selects which of the 64 PFB channels feeds output N. Lower 8 bits = + "packet" (``pfb_ch // 8``, 0-7), upper 8 bits = "index" within that + packet's 8-lane word (``pfb_ch % 8``, 0-7) -- computed by + ``AxisPFBReadoutV3.set_freq_int()`` as + ``id_val = (index << 8) + packet``. + * - ``PINC[0-3]_REG`` / ``freq[0-3]_reg`` + - 32 bits + - Per-output DDS frequency (fine-tuning on top of the selected PFB + channel's fixed center frequency). + * - ``POFF[0-3]_REG`` / ``phase[0-3]_reg`` + - 32 bits + - Per-output DDS phase offset. + +-------------------------------------------------------------------- +4. axis_pfb_readout_v4 +-------------------------------------------------------------------- + +4.1 Is v4 RTL-identical to v3? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +**No.** This was verified directly by diffing the RTL trees, not assumed from +the Python driver. ``axis_pfb_readout_v4`` reuses the *same* shared +sub-modules as v3 (``pfb_top.sv``, ``pfb_chsel.sv``, ``pfb.sv``, +``pfb_switch.v``, ``pfb_reorder.sv``, ``pfb_ctrl.vhd``, ``pfb_cfg.vhd`` are +byte-for-byte identical between the two IP directories -- confirmed with +``diff``), but the **top-level wrapper and its NOUT-sized instance arrays are +doubled from 4 to 8**: + +* ``pfb_top.sv``'s own header comment changes from *"The number of outputs is + fixed to 4 in this case"* (v3) to *"...fixed to 8 in this case"* (v4), and + its ``localparam NOUT`` literally changes from ``4`` to ``8``, adding 4 more + ``pfb_chsel`` generate-loop instances, 4 more ``ID[4-7]_REG`` ports, and 4 + more ``m[4-7]_axis_tdata`` outputs. +* ``ddsprod_v.sv`` goes from ``localparam N = 4`` (4 ``ddsprod`` instances) to + ``localparam N = 8`` (8 instances), with matching ``PINC[4-7]_REG``/ + ``POFF[4-7]_REG`` ports. +* ``axis_pfb_readout_v4.v``'s top level exposes 8 AXI-Stream masters + (``m0_axis``..``m7_axis``) instead of v3's 4, and its AXI-Lite address bus + widens from 6 bits (``s_axi_awaddr[5:0]``) to 8 bits + (``s_axi_awaddr[7:0]``) to fit the doubled register count (24 vs. 12). +* The underlying 64-channel PFB channelizer itself (``pfb.sv`` and everything + it instantiates, including the ``ssrfft_8x64`` FFT core) is **unchanged** + between v3 and v4 -- both still channelize the same 64 fixed bins from the + same ADC input; only how many of those channels can be simultaneously + routed out (and independently DDS-tuned) differs. + +So v4 is best described as *v3 with NOUT widened from 4 to 8*, not a +repackaging with identical RTL, and not an independent redesign of the +channelizer. This matches the Python driver docstring/registration exactly +(``AxisPFBReadoutV4(AxisPFBReadoutV3)`` overrides only ``NOUT = 8``, and its +docstring says *"This is identical to AxisPFBReadoutV3, but with 8 outputs +instead of 4"*) -- a case where the Python driver's claim and the RTL diff +independently agree. + +One thing this investigation could **not** determine, and does not guess at: +*why* v4 exists as a separate IP core (with its own VLNV, +``QICK:QICK:axis_pfb_readout_v4:1.0``) rather than v3 simply being +re-synthesized with a ``NOUT`` parameter -- unlike ``N`` (PFB channel count, +a real Verilog ``parameter`` on ``axis_pfb_readout_v3``/``v4``'s module +header), ``NOUT`` is a ``localparam`` hard-coded inside ``pfb_top.sv``/ +``ddsprod_v.sv``, not exposed as a module parameter, so making it +configurable would have required a nontrivial refactor of the fixed-width +port lists and register maps in both files -- forking to a new top-level +(and giving it a new IP core name) was evidently the path taken instead, but +no comment or commit message read in this session confirms that reasoning. + +4.2 Register Map +^^^^^^^^^^^^^^^^^ + +Same layout as v3, doubled: ``ID[0-7]_REG`` (16 bits each) at offsets 0-7, +then ``PINC[0-7]_REG``/``POFF[0-7]_REG`` (32 bits each) pairs at offsets +8/9, 10/11, ... 22/23 -- 24 registers total, matching +``AxisPFBReadoutV4``'s inherited ``_init_config()`` (which just runs v3's +same offset-generation loop with ``self.NOUT = 8``) and the widened 8-bit +AXI-Lite address bus in ``axis_pfb_readout_v4.v``/``axi_slv.v``. + +-------------------------------------------------------------------- +5. Python Interface +-------------------------------------------------------------------- + +5.1 ``AbsPFBReadout`` (shared base class) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``qick.drivers.readout.AbsPFBReadout(SocIP, AbsReadout)`` factors out what +all three versions have in common: + +* ``B_DDS = 32`` and a fixed ``IQ_OFFSET = -0.5`` -- the driver source + comments this as *"based on testing this seems like it might really be some + weird value like -0.48, even though this makes no sense"*, i.e. an + empirically-determined constant, not one derived from a specific rounding + operation in RTL (unlike, say, ``axis_dyn_readout_v1``'s offset -- see + :doc:`/readout_dynamic`). +* ``_init_config()`` derives ``DOWNSAMPLING = NCH // 2`` (the PFB's + 50%-overlap decimation) and ``CH_OFFSET = NCH // 2`` (the index of the PFB + channel centered at DC), and publishes ``pfb_nch``, ``pfb_nout``, + ``pfb_ch_offset``, ``pfb_dds_on_output`` into ``self.cfg`` for + ``QickConfig``/``calc_ro_regs()`` to use. +* ``configure_connections()`` traces the block's ``s_axis`` input back + through the RFDC (or, on boards with dual-ADC combiners like ZCU111/ + RFSoC4x2, through an intervening ``axis_combiner``) to determine which + physical ADC feeds this readout. +* ``configure()`` further divides ``f_dds``/multiplies ``fdds_div`` by + ``DOWNSAMPLING``, since the DDS's effective tuning range is reduced by both + the RFDC's decimation and the PFB's own 50%-overlap decimation. +* ``set_ch(f, out_ch, sel='product', gen_ch=None, phase=0)`` is the + debug-only, direct-register equivalent of ``declare_readout()`` for a PFB + output -- not used in normal programs, same caveat as + :meth:`.AbsReadout.set_all` on the single-tone readouts. + +5.2 Version-specific subclasses +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: Driver class attributes (from ``qick_lib/qick/drivers/readout.py``) + :header-rows: 1 + :widths: 26 16 16 16 26 + + * - + - ``NCH`` + - ``NOUT`` + - ``DDS_ON_OUTPUT`` + - ``HAS_OUTSEL`` + * - ``AxisPFBReadoutV2`` + - 8 (class constant) + - 4 (class constant) + - ``False`` + - ``True`` + * - ``AxisPFBReadoutV3`` + - read from the bitstream's ``N`` generic (``description['parameters']['N']``) + - 4 (class constant) + - ``True`` + - ``False`` + * - ``AxisPFBReadoutV4`` + - inherited from V3 (bitstream generic) + - 8 (class constant, only override vs. V3) + - ``True`` (inherited) + - ``False`` (inherited) + +``AxisPFBReadoutV2.set_freq_int(cfg)`` writes two registers per call: the +output's ``ch%dsel_reg`` (which of the 8 channels to route) and that +channel's ``freq%d_reg`` (the DDS tuning word) -- note this *overwrites* the +shared per-channel DDS setting, so the driver's own comment warns *"it's +assumed that channel collisions have already been checked ... a collision +will break the previously set channel"* if two outputs are pointed at the +same input channel with different frequencies. + +``AxisPFBReadoutV3.set_freq_int(cfg)`` validates ``pfb_ch``/``out_ch`` are +in-range, computes the ``(packet, index)`` pair for the ``ID`` register from +``pfb_ch``, and writes ``id``/``freq``/``phase`` for that output -- since the +DDS is per-output here, there's no collision risk analogous to v2's, and the +driver comment says so explicitly ("No need to check for collisions as they +are all truly independent"). ``AxisPFBReadoutV4`` inherits this method +unchanged; only ``NOUT`` differs. + +.. code-block:: python + :caption: Debug-only direct configuration of one PFB output (normally done via declare_readout()) + + from qick import * + + soc = QickSoc() + pfb = soc.readouts[i] # an AxisPFBReadoutV3 or AxisPFBReadoutV4 instance + + # Route PFB channel 5 to output 2, demodulated at 100 MHz. + pfb.set_ch(f=100.0, out_ch=2, sel='product') + +Normal QICK programs never call ``set_ch``/``set_freq_int`` directly -- +:meth:`.QickProgram.declare_readout` picks the PFB channel/output assignment +and frequency for you (via ``QickConfig.calc_ro_regs()``), exactly as +described in :doc:`/readout`'s Python Interface section for the single-tone +readouts. + +.. _readout-pfb-zcu216: + +-------------------------------------------------------------------- +6. Real-World Usage: ZCU216 "tpv2_std" +-------------------------------------------------------------------- + +The flagship ZCU216 board design (``firmware/Top/216/tpv2_std/bd_2023-1.tcl``, +tracked on branch ``feature/114-integrate-hog-fusesoc``) instantiates +**one** ``axis_pfb_readout_v4_0`` (VLNV ``QICK:QICK:axis_pfb_readout_v4:1.0``) +alongside **two** ``axis_dyn_readout_v1`` instances (:doc:`/readout_dynamic`) +and **ten** ``axis_avg_buffer`` instances (:doc:`/avg_buffer`) -- tracing the +block-diagram connections (``connect_bd_intf_net``) confirms exactly how that +10 breaks down, rather than assuming it's all attributable to one core: + +* ``axis_pfb_readout_v4_0`` exposes 8 outputs, ``m0_axis``..``m7_axis`` (its + full ``NOUT=8``, confirmed by 8 separate + ``axis_pfb_readout_v4_0_m[0-7]_axis`` nets in the .tcl). Each output feeds + its own ``axis_broadcaster`` (``axis_broadcaster_2`` through + ``axis_broadcaster_9``), which in turn drives its own dedicated + ``axis_avg_buffer`` (``axis_avg_buffer_2`` through ``axis_avg_buffer_9``) -- + **8 of the 10 avg_buffers on this board are fed by the single PFB readout + instance**, one per PFB output channel. +* The remaining 2 avg_buffers (``axis_avg_buffer_0``, ``axis_avg_buffer_1``) + are fed the same way (via their own broadcasters, + ``axis_broadcaster_0``/``axis_broadcaster_1``) by the two + ``axis_dyn_readout_v1`` instances' single ``m1_axis`` outputs. + +So the buffer count (10) is not a property of "how many readout instances +there are" (there are 3: 1 PFB + 2 dynamic) -- it's driven by *output ports*: +1 (per dynamic readout) x 2 + 8 (per PFB readout, its full NOUT) x 1 = 10. +This is exactly the PFB-vs-single-tone distinction from +:ref:`readout-pfb-general` above made concrete on real, currently-shipping +hardware: one PFB readout instance does the job of 8 single-tone readout + +buffer pairs, at the cost of those 8 channels sharing one fixed 64-way +channelizer (they can only demodulate PFB bins independently fine-tuned by +up to +/- half a bin, not arbitrary frequencies across the whole band +simultaneously). + +The PFB readout's AXI-Lite control port (``axis_pfb_readout_v4_0/s_axi``) is +mapped in the address space at offset ``0x000400101000``, range ``0x1000`` +(the .tcl's ``assign_bd_address`` call) -- a full 4 KiB page is reserved even +though the register map itself only spans 24 x 4 = 96 bytes (see +:ref:`readout-pfb-general`'s address-width comparison), consistent with the +AXI-Lite page-granularity convention used elsewhere in this address map +(not specific to the PFB readout). + +-------------------------------------------------------------------- +Related Documentation +-------------------------------------------------------------------- + +* :doc:`/readout` -- readout system overview; note its own single-tone + framing applies to :doc:`/readout_v2` and :doc:`/readout_dynamic`, not to + the PFB family described here. +* :doc:`/readout_v2` -- the single-tone, PYNQ-register-configured readout + the PFB readouts are architecturally different from (one tunable + demodulator vs. a fixed multi-channel bank). +* :doc:`/readout_dynamic` -- the tProc-configured single-tone readouts + (``axis_readout_v3``/``axis_dyn_readout_v1``) that share the ZCU216 board + design with ``axis_pfb_readout_v4`` (see :ref:`readout-pfb-zcu216`). +* :doc:`/avg_buffer` -- the buffer IP downstream of each PFB output; a PFB + readout with NOUT outputs typically drives NOUT separate avg_buffer + instances, as shown on the ZCU216. +* :doc:`topics/freq_matching` -- keeping generator and readout frequencies + in sync. diff --git a/docs/source/readout_v2.rst b/docs/source/readout_v2.rst new file mode 100644 index 000000000..0696ae301 --- /dev/null +++ b/docs/source/readout_v2.rst @@ -0,0 +1,160 @@ +======================================================== +Readout v2 (axis_readout_v2) - QICK Firmware +======================================================== + +.. contents:: + :local: + :depth: 2 + +**axis_readout_v2** is the digital down-converter (DDC) IP that sits between +the RFDC's ADC output and :doc:`/avg_buffer`. It is the readout used on +tProc-v1-style single-tone (non-multiplexed, non-PFB) readout channels. The +module lives under ``firmware/ip/axis_readout_v2/`` and is exposed to Python +through ``qick.drivers.readout.AxisReadoutV2``. + +-------------------------------------------------------------------- +1. General Description +-------------------------------------------------------------------- + +``axis_readout_v2`` mixes the ADC's real-valued input samples down to +baseband with an on-chip DDS, then applies an FIR anti-aliasing filter and +decimates by 8 before handing the complex (I, Q) stream to +:doc:`/avg_buffer`. Unlike the newer PFB-based readouts, it demodulates a +single, software-tunable frequency (no simultaneous multi-tone channelizer). + +The datapath, in order: + +1. **down_conversion** (``down_conversion.v``) -- complex multiply of the + real ADC input against a local DDS tone (``dds_compiler_0``), 16 parallel + lanes (``N_DDS=16`` samples/clock, matching the RFDC's parallel output). +2. **down_conversion_fir** (``down_conversion_fir.v``) -- FIR low-pass + (``fir_compiler_0``, fixed coefficients compiled into the bitstream) plus + decimation by 8. +3. Output to ``axis_avg_buffer``'s ``s_axis``. + +-------------------------------------------------------------------- +2. Frequency/Output Control (``ctrl.sv``) +-------------------------------------------------------------------- + +Register writes don't take effect directly -- ``ctrl.sv`` packs +``freq``/``phase``/``nsamp``/``outsel``/``mode`` into a single 83-bit +descriptor pushed through a FIFO (driven by the ``WE_REG`` pulse), then +drains that FIFO into the N_DDS DDS phase accumulators: + +.. list-table:: Descriptor fields (FIFO word, 83 bits) + :header-rows: 1 + :widths: 20 15 65 + + * - Field + - Width + - Description + * - ``freq`` + - 32 bits + - DDS tuning word (downconversion frequency). + * - ``phase`` + - 32 bits + - DDS phase offset. + * - ``nsamp`` + - 16 bits + - Sample count used when ``mode=0`` (see below). + * - ``outsel`` + - 2 bits + - Output source (see register map). + * - ``mode`` + - 1 bit + - 0: run for ``nsamp`` samples then stop. 1: run continuously + (periodic). + +The complex multiply itself: each of the 16 lanes takes one 16-bit real ADC +sample and multiplies it against that lane's complex DDS output +(``dds_compiler_0``, 32-bit {Q,I}), producing a 32-bit signed product per +component, rounded (add ``2**15``, keep bits ``[31:16]``) back down to 16-bit +I/Q before the output mux -- this is the "product" ``outsel`` value. + +-------------------------------------------------------------------- +3. Register Map +-------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + :widths: 25 15 60 + + * - Register + - Width + - Description + * - ``FREQ_REG`` + - 32 bits + - Downconversion DDS frequency. + * - ``PHASE_REG`` + - 32 bits + - DDS phase offset. + * - ``NSAMP_REG`` + - 16 bits + - Sample count for one-shot mode (``MODE_REG=0``); ignored in periodic + mode. + * - ``OUTSEL_REG`` + - 2 bits + - 0: product (mixer output, the normal downconverted signal). 1: dds + (raw local oscillator tone, for calibration/debugging). 2: input + (bypass -- the raw ADC sample, delay-matched to the other paths). + * - ``MODE_REG`` + - 1 bit + - 0: NSAMP (stop after ``NSAMP_REG`` samples). 1: Periodic (free-running + tone). + * - ``WE_REG`` + - 1 bit (pulse) + - Toggling this 0->1->0 pushes the current FREQ/PHASE/NSAMP/OUTSEL/MODE + register values into the descriptor FIFO as one atomic update. + +-------------------------------------------------------------------- +4. Key Parameters +-------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + :widths: 25 15 60 + + * - Parameter + - Value + - Notes + * - Downsampling ratio + - 8 + - Fixed FIR decimation; exposed to Python as ``DOWNSAMPLING = 8`` on + the driver class. + * - DDS/phase width + - 32 bits + - ``B_DDS = B_PHASE = 32`` on the driver. + * - IQ offset + - 0 + - Unlike the muxed/PFB readouts, ``axis_readout_v2`` introduces no + fixed I/Q rounding offset (``IQ_OFFSET = 0.0`` -- see + :meth:`.AcquireMixin._ro_offset`). + * - tProc control + - none + - This readout is PYNQ/software-configured only; it has no + ``tproc_ctrl`` connection (unlike the dynamic readouts, see + :doc:`/readout_dynamic`). + +-------------------------------------------------------------------- +5. Python Interface +-------------------------------------------------------------------- + +As with the buffer (:doc:`/avg_buffer`), normal programs configure this +readout via :meth:`.QickProgram.declare_readout` (``freq``, ``phase``, +``sel``, ``gen_ch``), not by writing registers directly -- see +:doc:`/readout`'s Python Interface section for the full +``declare_readout()``/``trigger()``/``acquire()`` workflow. +``AxisReadoutV2.set_all()``/``set_all_int()`` exist for direct register +access but are explicitly for debugging: *"Normally the [readout] is +configured based on parameters supplied in QickProgram.declare_readout()."* + +Related Documentation +---------------------- + +* :doc:`/readout` -- readout system overview and the normal + ``declare_readout()`` workflow. +* :doc:`/avg_buffer` -- the buffer downstream of this readout's output. +* :doc:`/readout_dynamic` -- the tProc-configured readouts + (``axis_readout_v3``/``axis_dyn_readout_v1``), for comparison. +* :doc:`topics/freq_matching` -- keeping generator and readout frequencies + in sync. diff --git a/docs/source/sg_int4_v2.rst b/docs/source/sg_int4_v2.rst new file mode 100644 index 000000000..631be8085 --- /dev/null +++ b/docs/source/sg_int4_v2.rst @@ -0,0 +1,382 @@ +================================================================== +Interpolated Signal Generator v2 (axis_sg_int4_v2) - QICK Firmware +================================================================== + +.. contents:: + :local: + :depth: 2 + +**axis_sg_int4_v2** is a single-tone, arbitrary-envelope waveform generator. +Unlike :doc:`/sg_v6`, which runs its DDS and envelope memory at the DAC's +full parallel sample rate, ``axis_sg_int4_v2`` stores the envelope at 1/4 of +the output rate and reconstructs the missing samples with a **4x +interpolation FIR filter** -- hence "int4". The module lives in the ``qick`` +firmware repository under ``firmware/ip/axis_sg_int4_v2/`` and is exposed to +Python through ``qick.drivers.generator.AxisSgInt4V2``. + +-------------------------------------------------------------------- +1. General Description +-------------------------------------------------------------------- + +Where "int4" comes from +^^^^^^^^^^^^^^^^^^^^^^^^ + +The Xilinx FIR Compiler instance ``fir_0`` inside ``signal_gen.v`` is +configured with ``Filter_Type = Interpolation`` and ``Interpolation_Rate = +4`` (read from ``firmware/ip/axis_sg_int4_v2/src/fir_0/fir_0.xci``). Each +cycle it consumes one complex envelope sample read from a single-rate BRAM +and produces **4** interpolated I/Q sample pairs, which are fed in parallel +to **4** DDS instances (``N_DDS = 4``, a ``localparam`` in +``axis_sg_int4_v2.v``). This matches the Python driver's own docstring for +the shared base class ``AbsIntSignalGen``: *"AXIS Signal Generator with +envelope x4 interpolation"* (``qick_lib/qick/drivers/generator.py``, and +``FS_INTERPOLATION = 4`` on that class -- though as of this reading that +attribute is defined but not actually read anywhere else in the driver +stack, so treat it as documentation rather than as something that changes +behavior). + +This is the key architectural difference from :doc:`/sg_v6` (and the older +``axis_signal_gen_v4``/``v5``, referred to together as SG-v4/v5/v6 in the +Python driver): SG-v6 stores the envelope **pre-expanded**, with one BRAM +pair (real/imag) per parallel DDS lane (``N_DDS`` pairs, default 16), so +``maxlen = 2**N * N_DDS`` samples of table are actually stored. This int4 +generator instead keeps a **single** real BRAM and a **single** imag BRAM +(see ``signal_gen_top.v``, instances ``mem_real_i``/``mem_imag_i``) holding +only ``2**N`` raw samples, and lets the FIR do the x4 expansion on the fly -- +which is why the Python driver's ``AbsIntSignalGen._init_config`` computes +``self.cfg['maxlen'] = 2**env_n`` (no ``* n_dds`` factor), with the comment +*"Table is interpolated. Length is given only by parameter N."* Both designs +still emit ``N_DDS`` output samples per clock on ``m_axis_tdata_o``; int4 +just trades BRAM area for a FIR filter to get there from a quarter-rate +table. + +Like SG-v6, this generator is single-output (one complex tone per channel, +via its own DDS + envelope multiplier) -- it is not multiplexed like +``axis_sg_mux4_v1``, which drives several simultaneous tones from one +channel. + +.. note:: + + Unlike SG-v6, ``axis_sg_int4_v2`` has **no** ``GEN_DDS``/``ENVELOPE_TYPE`` + synthesis parameters: it always instantiates the DDS+multiplier path (no + baseband-only mode) and always builds separate real/imag BRAMs (no + real-only envelope mode). Confirmed by the absence of those parameters in + ``axis_sg_int4_v2.v``/``signal_gen_top.v``/``signal_gen.v``, in contrast + to ``firmware/ip/axis_signal_gen_v6/src/signal_gen_top.v`` which has both. + +Because the DDS only needs to synthesize the frequency band around the +interpolated (quarter-rate) envelope, this generator relies on the RFDC's +own on-chip mixer for final upconversion: ``AbsIntSignalGen.HAS_MIXER = +True`` (whereas SG-v4/v5/v6's ``AxisSignalGen.HAS_MIXER = False``). In +practice this means ``QickProgram.declare_gen()`` requires a ``mixer_freq`` +argument for this channel (``qick_lib/qick/qick_asm.py``, ``declare_gen``: +*"generator %d has a digital mixer, but no mixer_freq was defined"*), which +is not the case for SG-v6. + +Version note (v1 -> v2) +^^^^^^^^^^^^^^^^^^^^^^^^ + +A brief diff against the sibling ``firmware/ip/axis_sg_int4_v1/`` shows the +two share essentially the same RTL structure (same module names, same +FIR/interpolation-by-4 configuration, same descriptor field layout). The one +substantive change is DDS/phase resolution: v1's ``dds_compiler_0`` is +configured with ``Phase_Width = 16`` (``Frequency_Resolution = 3906.25``, +i.e. Hz-scale steps), while v2's is configured with ``Phase_Width = 32`` +(``Frequency_Resolution = 0.06``) -- a large increase in tuning resolution. +This propagates through the whole datapath: the ``freq``/``phase`` fields of +the waveform descriptor grow from 16 to 32 bits each, and the descriptor +itself grows from 85 bits (v1, ``s1_axis_tdata`` is ``[84:0]``) to 160 bits +(v2, ``s1_axis_tdata`` is ``[159:0]``) to carry the wider fields plus +padding. This is exactly mirrored in the Python driver: ``AxisSgInt4V1`` sets +``B_DDS = B_PHASE = 16`` ("Interpolated generator with 16-bit frequency and +phase"), ``AxisSgInt4V2`` sets ``B_DDS = B_PHASE = 32`` ("Interpolated +generator with 32-bit frequency and phase"). + +-------------------------------------------------------------------- +2. Synthesis Parameters +-------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + :widths: 20 15 55 + + * - Parameter + - RTL Default + - Description + * - ``N`` + - 12 (``axis_sg_int4_v2.v``) + - Envelope memory address width. Table depth is ``2**N`` raw (complex) + samples; ``signal_gen_top.v``/``signal_gen.v`` themselves default to + ``N = 16`` when instantiated standalone, but the top-level wrapper + overrides this to 12. Real deployments commonly override it further + per channel -- e.g. ``firmware/projects/qick_tprocv2_216_standard/ + bd_2023-1.tcl`` instantiates different ``axis_sg_int4_v2`` copies with + ``CONFIG.N`` values of 13 and 14 -- so always read the deployed value + from ``soc.cfg['gens'][i]['maxlen']`` rather than assuming a default. + * - ``N_DDS`` + - 4 (fixed) + - Number of parallel DDS lanes / interpolated output samples per clock. + Declared as a ``parameter`` on ``signal_gen_top``/``signal_gen``, but + the top-level ``axis_sg_int4_v2.v`` wrapper pins it to a + ``localparam`` value of 4 -- it is not exposed as a customizable IP + parameter the way SG-v6's ``N_DDS`` is. + +-------------------------------------------------------------------- +3. Datapath +-------------------------------------------------------------------- + +The pipeline, in order (all in ``signal_gen.v`` unless noted): + +1. **ctrl (``ctrl.sv``)** -- an FSM (states ``READ_ST``/``CNT_ST``) pops one + 160-bit descriptor from the waveform FIFO into ``fifo_dout_r``, then holds + its fields active for ``nsamp`` clock cycles (each cycle advances the + envelope read address by 1 and advances each of the 4 DDS phase + accumulators by ``pinc``, with per-lane phase offsets ``pinc*0..pinc*3`` + so the 4 parallel DDS outputs are phase-continuous with each other). When + the count expires, it either fetches the next queued descriptor or, if + ``mode`` = periodic, keeps replaying the current one. +2. **Envelope memory (``mem_real_i``/``mem_imag_i``, ``bram.v``/dual-port + BRAM in ``signal_gen_top.v``)** -- one real and one imag BRAM, ``N`` bits + of address, 16 bits of data each, read at 1 address per clock (write side + is in the ``s0_axis_aclk`` domain via ``data_writer``, read side in + ``aclk``). +3. **Interpolation FIR (``fir_0``)** -- Xilinx FIR Compiler, interpolation + filter, rate 4, cycle latency 11 (+1 registered output = 12 per the + comment in ``signal_gen.v``). Expands the 1 complex envelope sample/clock + into 4 (``env_dout``, ``N_DDS*32`` bits wide). +4. **DDS (``dds_compiler_0``, x4 instances)** -- Xilinx DDS Compiler, + ``Phase_Width = 32``, ``Output_Width = 16`` (both real and imag), latency + 10 cycles. +5. **Complex multiply** -- each of the 4 lanes multiplies its DDS output + (I, Q) against the corresponding interpolated envelope sample: + ``real = I_dds*I_env - Q_dds*Q_env``, ``imag = I_dds*Q_env + Q_dds*I_env``, + each 32-bit partial product truncated to the top 16 bits (a + round-to-nearest-ish scheme: the accumulator's bit 30 is duplicated into + bit 31 before truncation, i.e. ``{p[30], p[30:0]}``, then bits ``[31:16]`` + are kept). This 16-bit result is the "product" ``outsel``. +6. **Output source mux (``src_la``)** -- per lane, selects between the + product (0), the raw DDS output (1), the raw interpolated complex + envelope sample -- both real and imag, unlike the readout's "input" + mode which is real-only -- for ``outsel = 2`` + (``{env_imag_la[i], env_real_la[i]}``), or an all-zero word (3, the + implicit default of the mux). +7. **Gain multiply + rounding** -- the muxed sample is multiplied by a + 16-bit signed ``gain`` register (latency-aligned via a 19-cycle + ``latency_reg``), and the 32-bit product is rounded down to 16 bits per + component (``prodg_y_full_*_r[30 -: 16]``, i.e. keep bits 30 down to 15 -- + a right-shift-by-15 round rather than a symmetric round-to-nearest). +8. **Output register** -- while the waveform is active (``en_la_r``), the + rounded, gain-scaled sample (``round_r``) is driven on + ``m_axis_tdata_o``. Once inactive, the output holds the value selected by + ``stdysel``: the last active sample (``stdysel = "last"``, code 0 -- and + specifically the 4th of the last active clock's 4 lanes, broadcast to all + 4 output lanes, since ``last_r[i] <= round[N_DDS-1]`` for every ``i``) or + all zeros (``stdysel = "zero"``, code 1). + +.. note:: + + ``params2pulse()`` in ``qick_lib/qick/asm_v2.py`` has an explicit + workaround specific to this generator family (``axis_sg_int4_v1`` and + ``axis_sg_int4_v2``, but not SG-v6): for ``flat_top`` pulses, an extra + zero-gain, minimum-length ``"dds"``-outsel waveform is appended after the + ramp-down, with the comment *"workaround for FIR bug: we play a + zero-gain min-length DDS pulse after the ramp-down, which brings the FIR + to zero."* This is presumably needed because the interpolation FIR (step + 3 above) has state/history that would otherwise bleed into the following + pulse; SG-v6 has no FIR in its envelope path and needs no such + workaround. + +-------------------------------------------------------------------- +4. Waveform Descriptor (S1_AXIS) +-------------------------------------------------------------------- + +``s1_axis_tdata`` is a 160-bit word pushed into a 160-bit-wide, 16-entry +FIFO (``fifo_i`` in ``signal_gen_top.v``, same depth as SG-v6's). Field +layout, read directly from the header comment and bit-slice assignments in +``ctrl.sv``: + +.. list-table:: Waveform descriptor fields + :header-rows: 1 + :widths: 15 15 15 55 + + * - Field + - Bits + - Width + - Description + * - ``freq`` + - ``[31:0]`` + - 32 + - DDS frequency tuning word for all 4 lanes (phase increment per + clock, before the x4 per-lane phase offset). + * - ``phase`` + - ``[63:32]`` + - 32 + - DDS phase offset. + * - ``addr`` + - ``[79:64]`` + - 16 + - Start address of the envelope in ``mem_real``/``mem_imag``. + * - (unused) + - ``[95:80]`` + - 16 + - Not read by ``ctrl.sv``. + * - ``gain`` + - ``[111:96]`` + - 16 + - Signed output gain. + * - (unused) + - ``[127:112]`` + - 16 + - Not read by ``ctrl.sv``. + * - ``nsamp`` + - ``[143:128]`` + - 16 + - Number of clock cycles (each emitting ``N_DDS`` = 4 output samples) + the descriptor stays active in one-shot mode. + * - ``outsel`` + - ``[145:144]`` + - 2 + - Output source select: 0 product, 1 dds, 2 input (envelope), 3 zero. + * - ``mode`` + - 146 + - 1 + - 0 one-shot (stop after ``nsamp``), 1 periodic (replay). + * - ``stdysel`` + - 147 + - 1 + - 0 last (hold last sample), 1 zero. + * - ``phrst`` + - 148 + - 1 + - Reset the DDS phase accumulator when this descriptor loads. + * - (unused) + - ``[159:149]`` + - 11 + - Not read by ``ctrl.sv``. + +This layout is bit-for-bit identical to SG-v6's 160-bit descriptor (same +field widths, same bit positions -- compare the header comment in this +IP's ``ctrl.sv`` against ``firmware/ip/axis_signal_gen_v6/src/ctrl.sv``). +Confirmed in the routing firmware itself: in +``firmware/projects/qick_tprocv2_216_standard/bd_2023-1.tcl``, the +``axis_sg_int4_v2_0`` instance's ``s1_axis`` is wired to +``sg_translator_5/m_gen_v6_axis`` -- i.e. it uses the **same** +``sg_translator`` output path (``OUT_TYPE = 0``, "gen_v6") as SG-v6, not the +dedicated, 88-bit, 16-bit-freq/phase ``int4_v1`` translation path +(``OUT_TYPE = 1``) that ``axis_sg_int4_v1`` uses. ``sg_translator`` +(``firmware/ip/qick_sg_translator/src/sg_translator.v``) is the block that +sits between the tProcessor's generic 168-bit wave-memory word (``freq``, +``phase``, ``env``, ``gain``, ``length``, ``conf``) and this generator's +160-bit ``s1_axis`` -- it truncates the tProc's 32-bit ``length`` field down +to the 16-bit ``nsamp`` here, but passes ``freq``/``phase`` through +unmodified at full 32-bit width (unlike the truncation ``int4_v1`` needs). + +-------------------------------------------------------------------- +5. Register Map (S_AXI, AXI-Lite) +-------------------------------------------------------------------- + +``axi_slv.vhd`` implements a 32-bit AXI-Lite slave with a 6-bit address bus +(16 possible word-aligned registers), of which only two are wired to the +rest of the IP: + +.. list-table:: + :header-rows: 1 + :widths: 20 15 15 50 + + * - Register + - Offset + - Width + - Description + * - ``START_ADDR_REG`` + - 0x00 + - 32 bits + - Starting address in envelope memory for the next block of samples + written via ``S0_AXIS``. + * - ``WE_REG`` + - 0x04 + - bit 0 + - Envelope-memory write enable. The ``data_writer`` FSM + (``data_writer.vhd``) waits in ``INIT_ST`` until this is asserted, + latches ``START_ADDR_REG`` as the write pointer, then streams + ``S0_AXIS`` samples into ``mem_real``/``mem_imag`` (32-bit words: + bits ``[15:0]`` real, ``[31:16]`` imag), auto-incrementing the + address each valid beat. + +This matches ``AbsIntSignalGen.REGISTERS = {'start_addr_reg': 0, 'we_reg': +1}`` in the Python driver (note: these are *register indices*, i.e. +``we_reg`` is word offset 1 = byte offset 0x04, not bit 1 of word 0). + +-------------------------------------------------------------------- +6. Python Interface +-------------------------------------------------------------------- + +The class hierarchy (``qick_lib/qick/drivers/generator.py``): + +* ``AbsSignalGen`` -- common signal-gen config: ``MAXV``, ``set_nyquist()``, + ``set_mixer_freq()``/``get_mixer_freq()`` (only usable if ``HAS_MIXER``). +* ``AbsArbSignalGen(AbsSignalGen)`` -- adds the envelope-memory ``load()`` + method (DMA transfer + ``START_ADDR_REG``/``WE_REG`` pulsing), plus + ``SAMPS_PER_CLK`` (1 for this generator -- envelope samples are loaded + one per clock, unlike SG-v6's 16) and ``MAXV_SCALE``. +* ``AbsPulsedSignalGen(AbsSignalGen)`` -- adds tProcessor-port discovery + (``TPROC_PORT = 's1_axis'``) for tProc-triggered playback. +* ``AbsIntSignalGen(AbsArbSignalGen, AbsPulsedSignalGen)`` -- the shared + base for both int4 versions: ``HAS_MIXER = True``, + ``FS_INTERPOLATION = 4``, ``MAXV_SCALE = 0.9`` (reduced from the default + 1.0 "to prevent interpolation overshoot: the output of the interpolation + filter may exceed the max value of the input points," per the class + docstring), ``REGISTERS = {'start_addr_reg': 0, 'we_reg': 1}``, and + ``maxlen = 2**N`` (table is interpolated -- see Section 1). +* ``AxisSgInt4V2(AbsIntSignalGen)`` -- ``bindto = ['user.org:user: + axis_sg_int4_v2:1.0', 'QICK:QICK:axis_sg_int4_v2:1.0']``, + ``B_DDS = B_PHASE = 32``. + +Normal QICK programs don't touch these registers directly -- they go through +:meth:`.QickProgram.declare_gen` (to set Nyquist zone and, for this +generator, the required ``mixer_freq``) and +:meth:`.QickProgramV2.add_pulse` (style ``"arb"`` or ``"flat_top"``, using +an envelope loaded with :meth:`.QickProgram.add_envelope`). + +.. code-block:: python + :caption: Configuring and playing a pulse on an int4-v2 channel + + from qick import * + import numpy as np + + soc = QickSoc() + gen_ch = 0 # must be an axis_sg_int4_v2 channel, e.g. soc['gens'][gen_ch]['type'] == 'axis_sg_int4_v2' + + class MyProgram(QickProgramV2): + def _initialize(self, cfg): + # this generator has a mixer (HAS_MIXER=True), so mixer_freq is required + self.declare_gen(ch=gen_ch, nqz=1, mixer_freq=500.0, ro_ch=0) + + # envelope samples are int16; length is checked against the + # deployed maxlen = 2**N for this channel + n = 400 + sigma = n / 8 + env = 32767 * np.exp(-0.5 * ((np.arange(n) - n/2) / sigma)**2) + self.add_envelope(ch=gen_ch, name="gauss", idata=env.astype(np.int16)) + + self.add_pulse(ch=gen_ch, name="pulse1", style="arb", + freq=100.0, phase=0, gain=0.5, + envelope="gauss", outsel="product") + + def _body(self, cfg): + self.pulse(ch=gen_ch, name="pulse1", t=0) + +-------------------------------------------------------------------- +Related Documentation +-------------------------------------------------------------------- + +* :doc:`/sg_v6` -- SG-v6, the full-rate/full-BRAM sibling generator this + page repeatedly compares against. +* :doc:`/tprocv2_trm` -- tProcessor v2 sequencing (``WPORT_WR``/``add_pulse`` + path that ultimately fills this generator's ``S1_AXIS`` via + ``qick_sg_translator``). +* :doc:`/firmware` -- Firmware overview and channel assignments. +* :doc:`topics/gen_config` -- ``outsel``/``mode``/``stdysel`` semantics + (shared across all pulsed generators in this doc set). +* :doc:`topics/freq_matching` -- keeping generator and readout frequencies + in sync (relevant here because of the required ``mixer_freq``). +* `axis_sg_int4_v2 source code `_ diff --git a/docs/source/sg_mixmux8.rst b/docs/source/sg_mixmux8.rst new file mode 100644 index 000000000..af61f939a --- /dev/null +++ b/docs/source/sg_mixmux8.rst @@ -0,0 +1,358 @@ +============================================================================== +Multiplexed Signal Generator with Mixer (axis_sg_mixmux8_v1) - QICK Firmware +============================================================================== + +.. contents:: + :local: + :depth: 2 + +**axis_sg_mixmux8_v1** is an 8-tone multiplexed (muxed) signal generator, +almost identical in its control logic to :doc:`/sg_mux8` +(``axis_sg_mux8_v1``), but with a **complex (I/Q) datapath** so that its +output can drive the RFDC's own digital mixer/NCO. The module lives under +``firmware/ip/axis_sg_mixmux8_v1/`` and is exposed to Python through +``qick.drivers.generator.AxisSgMixMux8V1``. + +-------------------------------------------------------------------- +1. General Description +-------------------------------------------------------------------- + +Like ``axis_sg_mux8_v1``, this block plays up to 8 independent, phase-coherent +CW tones simultaneously: each tone has its own frequency (``PINCx_REG``), +phase (``POFFx_REG``) and gain (``GAINx_REG``), and the tProcessor selects +which subset of the 8 tones is active for a given pulse via an 8-bit mask +and a sample count, pushed onto ``s_axis`` (see Section 3.2 below). The +8 (masked) tones are summed together and streamed out at up to ``N_DDS`` +samples per clock. + +The one substantive RTL difference from ``axis_sg_mux8_v1`` -- confirmed by +diffing the two IPs' ``src/`` directories file-by-file (``diff -rq +firmware/ip/axis_sg_mux8_v1/src firmware/ip/axis_sg_mixmux8_v1/src``) -- is +that **every per-tone DDS core is configured as a complex (I/Q) oscillator +instead of a real-valued one**, and the entire summation/quantization +datapath downstream of it is duplicated to carry both components. Concretely: + +* In ``dds_top.v``'s ``dds_compiler_0`` (the Xilinx DDS Compiler core), the + ``Output_Selection`` parameter is ``"Sine"`` in ``axis_sg_mux8_v1`` (a + real-valued 16-bit output) versus ``"Sine_and_Cosine"`` in + ``axis_sg_mixmux8_v1`` (a packed 32-bit ``{cosine, sine}`` output). This is + the actual source of the "mix" in the name. +* ``dds_dout_o``, the DDS-to-gain-stage bus, is ``N_DDS*16`` bits wide in + ``axis_sg_mux8_v1`` and ``N_DDS*32`` bits wide in ``axis_sg_mixmux8_v1`` + (16-bit real vs. 16-bit-I + 16-bit-Q per DDS lane). +* The per-tone gain multiply in ``dds_top.v`` (``prod_a_real = dds_dout_la[i]`` + in mux8 vs. ``prod_a_real = dds_dout_la[i][15:0]`` / + ``prod_a_imag = dds_dout_la[i][31:16]`` in mixmux8) is duplicated: the + *same* signed 16-bit ``GAIN_REG`` value is multiplied independently against + the real and imaginary DDS samples. This is a real (scalar) amplitude + scale of a complex sample, **not** a complex/quadrature multiply -- there + is no cross term (no ``I*sin(LO) - Q*cos(LO)``-style rotation) anywhere in + this IP's RTL. +* In ``sg_mux8.v``, the 8-tone masking, the 7-stage pairwise adder tree that + sums the (up to 8) active tones per DDS lane, and the mask-popcount-based + output quantization (see Section 3.3) are all bit-for-bit the same logic + as ``axis_sg_mux8_v1``'s -- just instantiated twice, once for the real + (I) rail and once for the imaginary (Q) rail, in parallel. ``m_axis_tdata_o`` + ends up ``N_DDS*32`` bits wide (16-bit I + 16-bit Q per DDS lane) instead of + ``axis_sg_mux8_v1``'s ``N_DDS*16`` bits (real only). +* ``axi_slv.v`` (the AXI-Lite register file), ``ctrl.sv`` (the FIFO-drain / + mask / enable FSM), ``phase_ctrl.sv`` (the phase accumulator, including its + use of ``mult_32x32.v``), ``latency_reg.v`` and ``synchronizer_n.vhd`` are + **byte-identical files** between the two IPs (confirmed by ``diff -rq`` + reporting no difference for any of them). There is **no additional + register, FSM, or signal path in this IP's own RTL for an internal mixer** + -- no ``MIXFREQ``-style register, no second NCO, no per-lane local + oscillator anywhere in ``axis_sg_mixmux8_v1``'s source. + +So where is the "mixer"? It is the RFDC's (RF Data Converter) own digital +mixer/NCO on the DAC tile, external to this IP -- ``axis_sg_mixmux8_v1`` +simply produces the complex (I/Q) samples that RFDC mixer needs as input. +This is corroborated by the Python driver (``qick_lib/qick/drivers/generator.py``): + +* ``AxisSgMux8V1``'s docstring: *"AXIS Signal Generator with 8 muxed outputs, + fullspeed (**no DAC mixer**)."* versus ``AxisSgMixMux8V1``'s: *"AXIS Signal + Generator with 8 muxed outputs, **using DAC mixer**."* +* ``AbsSignalGen.set_mixer_freq()``/``get_mixer_freq()`` (the methods that + back this behavior for every ``HAS_MIXER=True`` generator, including this + one) call straight through to ``self.rf.set_mixer_freq(self['dac'], f, + ...)`` -- i.e. they configure the RFDC block driver, not any register + inside ``axis_sg_mixmux8_v1`` itself. +* ``AxisConstantIQ`` (another ``HAS_MIXER=True`` generator) states the same + architecture explicitly: *"Plays a constant IQ value, which gets mixed + with the DAC's built-in oscillator."* + +Because the mixer frequency is a single value set on the DAC tile +(``set_mixer_freq(ch, f)`` takes one ``f`` for the whole generator channel, +and ``QickConfig.calc_muxgen_regs()`` computes every tone's ``PINC`` as +``f_dds = freq - mixer_freq`` relative to that one value), **the local +oscillator is shared across all 8 muxed tones on a channel, not independent +per tone/lane**. The 8 tones are combined digitally at baseband (each +keeping its own ``PINC``/``POFF``/``GAIN`` relative to that shared center +frequency) and the RFDC mixer then shifts the *entire already-summed comb* +up (or down) in frequency, which is what lets ``axis_sg_mixmux8_v1`` +(unlike ``axis_sg_mux8_v1``) place its whole multi-tone output away from DC, +including outside the DAC's first Nyquist zone. + +.. note:: + + This page documents only ``axis_sg_mixmux8_v1``'s own RTL and driver. + The RFDC mixer/NCO itself (register layout, valid frequency ranges, + Nyquist-zone handling) lives in AMD's RF Data Converter IP and the + ``qick.qick.AxisRFDC``-family driver, not in this IP -- see + :doc:`topics/freq_matching` for the software-level picture of how + generator and readout frequencies are kept consistent. + +-------------------------------------------------------------------- +2. Synthesis Parameters +-------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + :widths: 20 15 55 + + * - Parameter + - RTL Default + - Description + * - ``N_DDS`` + - 2 + - Number of parallel DDS/output lanes (samples produced per clock on + ``m_axis_tdata_o``). Each of the 8 tone generators instantiates + ``N_DDS`` parallel ``dds_compiler_0`` cores; the 8 tones are then + summed lane-by-lane. Real board builds typically use a larger value + than the RTL default -- the Python driver stores it as ``gen.NDDS`` + (read from the block's HWH parameters) but does **not** publish it in + ``soc['gens'][i]``, so read ``soc.gens[i].NDDS`` directly if you need + it at runtime. + +There is no synthesis parameter that changes the mixer/complex behavior -- +that is hard-wired into the ``dds_compiler_0`` IP core configuration +(``Output_Selection = "Sine_and_Cosine"``), unlike ``ENVELOPE_TYPE`` or +``GEN_DDS`` on the arbitrary-waveform generators (:doc:`/sg_v6`). + +-------------------------------------------------------------------- +3. Datapath +-------------------------------------------------------------------- + +3.1 Top-level structure +^^^^^^^^^^^^^^^^^^^^^^^ + +``axis_sg_mixmux8_v1.v`` instantiates exactly two blocks (this wiring is +identical in shape to ``axis_sg_mux8_v1.v``, differing only in the +``m_axis_tdata`` bus width): + +* ``axi_slv`` -- the AXI-Lite register file (Section 4). +* ``sg_mux8`` -- the FIFO, control FSM, 8 DDS/gain stages, adder tree and + quantizer (Sections 3.2-3.3). + +3.2 Waveform trigger FIFO and control FSM +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The tProcessor triggers playback by pushing a 40-bit descriptor onto +``s_axis_tdata_i`` (via a 16-deep FIFO, ``fifo_wr_en = s_axis_tvalid_i``): + +.. list-table:: Waveform-trigger descriptor (``s_axis_tdata_i``, 40 bits) + :header-rows: 1 + :widths: 20 15 65 + + * - Field + - Bits + - Description + * - ``mask`` + - ``[39:32]`` (8 bits) + - One bit per tone (bit *i* enables tone *i*'s ``GAINi``/``PINCi``/ + ``POFFi`` in the sum for this playback burst). + * - ``nsamp`` + - ``[31:0]`` + - Number of output samples (cycles) to play before returning to idle. + +``ctrl.sv`` is a small FSM (``READ_ST -> CNT0_ST -> CNT_ST -> READ_ST``) +that drains this FIFO one descriptor at a time, latches ``mask``/``nsamp``, +asserts the shared output-enable (``en_o``, latency-matched to the datapath +via a ``latency_reg``) for ``nsamp`` cycles, and holds ``mask_o`` for the +duration. This file is byte-identical between ``axis_sg_mux8_v1`` and +``axis_sg_mixmux8_v1``. + +3.3 Per-tone DDS, gain, and the adder/quantizer tree +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``sg_mux8.v`` instantiates 8 ``dds_top`` blocks (one per tone), each driven +by that tone's ``PINCx_REG``/``POFFx_REG``/``GAINx_REG``. Inside +``dds_top.v``: + +1. ``phase_ctrl`` computes ``N_DDS`` parallel, phase-coherent phase/PINC + words (using ``mult_32x32`` for the ``PINC*N_DDS`` and + ``PINC*sample_count`` products needed to keep the ``N_DDS`` lanes + phase-coherent), latched on a rising edge of the (resynchronized) + ``WE_REG``. +2. Each lane's ``dds_compiler_0`` produces one DDS sample per clock -- + real-only (``Sine``) in ``axis_sg_mux8_v1``, complex I/Q + (``Sine_and_Cosine``) in ``axis_sg_mixmux8_v1``. +3. The (real, or real+imag) DDS sample(s) are scaled by that tone's signed + 16-bit ``GAIN_REG`` (``prod_real = I*gain``, and in mixmux8 also + ``prod_imag = Q*gain``), each independently rounded back down to 16 bits. + +Back in ``sg_mux8.v``, for each DDS lane the (up to 8) tones selected by +``mask`` are summed via a 7-stage pairwise binary adder tree +(``add0..add7 -> sum0..sum3 -> sum4..sum5 -> sum6``), growing from 16 to 19 +signed bits to avoid overflow, then quantized back down based on +``qsel = popcount(mask)`` (the number of simultaneously active tones): + +.. list-table:: Output quantization vs. number of active tones + :header-rows: 1 + :widths: 20 20 60 + + * - ``qsel`` (active tones) + - Shift + - Bits taken from the 19-bit ``sum6`` + * - 1 + - none + - ``[15:0]`` + * - 2 + - ``>>1`` + - ``[16:1]`` + * - 3 or 4 + - ``>>2`` + - ``[17:2]`` + * - 5, 6, 7 or 8 + - ``>>3`` + - ``[18:3]`` + +This scaling (average rather than a raw sum) is applied identically and +independently to the real and imaginary sums in ``axis_sg_mixmux8_v1``; in +``axis_sg_mux8_v1`` it is applied only to the single real sum. The final +per-DDS-lane output word on ``m_axis_tdata_o`` is +``{dout_imag[i], dout_real[i]}`` (32 bits: Q in the high 16 bits, I in the +low 16) in ``axis_sg_mixmux8_v1``, versus just ``dout_real[i]`` (16 bits) in +``axis_sg_mux8_v1``. + +-------------------------------------------------------------------- +4. Register Map +-------------------------------------------------------------------- + +The AXI-Lite register file (``axi_slv.v``, byte-identical to +``axis_sg_mux8_v1``'s) is a flat array of 32-bit words, word-addressed from +``s_axi_awaddr[7:2]``. Verified directly from the RTL's address-decode +``case`` statement and its register->port ``assign`` list at the bottom of +``axi_slv.v``: + +.. list-table:: + :header-rows: 1 + :widths: 20 15 15 50 + + * - Register + - Byte address + - Width + - Description + * - ``PINC0_REG`` .. ``PINC7_REG`` + - ``0x00`` .. ``0x1C`` + - 32 bits + - DDS frequency tuning word for tone 0..7 (``B_DDS = 32`` on the + driver). + * - ``POFF0_REG`` .. ``POFF7_REG`` + - ``0x20`` .. ``0x3C`` + - 32 bits + - DDS phase offset for tone 0..7 (``B_PHASE = 32`` on the driver). + * - ``GAIN0_REG`` .. ``GAIN7_REG`` + - ``0x40`` .. ``0x5C`` + - 32 bits (AXI word); **only bits [15:0] reach the hardware** + - Signed gain for tone 0..7. The AXI-Lite word is 32 bits wide, but in + both ``axis_sg_mux8_v1.v`` and ``axis_sg_mixmux8_v1.v`` the + ``GAINx_REG`` wire connecting ``axi_slv`` to ``sg_mux8``/``dds_top`` + is declared ``[15:0]`` -- Verilog silently truncates to the low 16 + bits, so only a signed 16-bit gain actually reaches the multiplier. + In practice this is not observable from software, since the driver's + ``MAXV = 2**15-2`` keeps gain values within signed-16-bit range + anyway -- but it means the register is *not* a full 32-bit gain + field, despite being AXI-mapped as one. + * - ``WE_REG`` + - ``0x60`` + - 1 bit (bit 0 of the word; pulse) + - Write-enable strobe. A 0->1 transition (resynchronized per-DDS by + ``synchronizer_n`` inside ``phase_ctrl``) latches the *current* + values of all 8 ``PINCx``/``POFFx``/``GAINx`` registers into the + datapath atomically -- writing individual ``PINCx``/``POFFx``/ + ``GAINx`` registers alone has no effect on the generator's output + until ``WE_REG`` is pulsed. + +This matches, word for word, the register map that +``AbsMuxSignalGen._init_config()`` builds programmatically in the Python +driver (``pinc0..7_reg`` at word indices 0-7, ``poff0..7_reg`` at 8-15, +``gain0..7_reg`` at 16-23, ``we_reg`` at 24) -- no discrepancy was found +between the RTL address decode and the driver's register offsets. + +-------------------------------------------------------------------- +5. Python Interface +-------------------------------------------------------------------- + +``AxisSgMixMux8V1`` (``qick_lib/qick/drivers/generator.py``) is a thin +subclass of ``AbsMuxSignalGen`` (shared with ``AxisSgMux8V1`` and the other +muxed generators) that only sets the class attributes describing this IP's +capabilities: + +.. code-block:: python + + class AxisSgMixMux8V1(AbsMuxSignalGen): + bindto = ['user.org:user:axis_sg_mixmux8_v1:1.0', + 'QICK:QICK:axis_sg_mixmux8_v1:1.0'] + HAS_MIXER = True + B_DDS = 32 + N_TONES = 8 + HAS_GAIN = True + HAS_PHASE = True + B_PHASE = 32 + +The only difference from ``AxisSgMux8V1``'s class attributes is +``HAS_MIXER = True`` (vs. ``False``) -- everything else (tone count, +frequency/phase/gain widths) is the same. + +As with the other pulsed generators, most QICK programs never call the +low-level register-setting methods directly -- they configure this +generator through :meth:`.QickProgram.declare_gen` and then play tones by +selecting a subset of them with ``mask``: + +.. code-block:: python + :caption: Configuring and playing tones on axis_sg_mixmux8_v1 + + from qick import * + + soc = QickSoc() + prog = QickProgram(soc) # or QickProgramV2, depending on tProc version + + # gen_ch 0 is bound to an axis_sg_mixmux8_v1 instance in this example. + # Because HAS_MIXER=True, a mixer_freq is required; it sets the RFDC's + # NCO, shared by all 8 tones on this channel. + prog.declare_gen( + ch=0, + nqz=1, + mixer_freq=500.0, # MHz, shared LO for all 8 tones + mux_freqs=[-50.0, 0.0, 75.0], # MHz, offsets from mixer_freq + mux_gains=[0.9, 1.0, 0.5], + mux_phases=[0, 0, 90], + ro_ch=0, # frequency-match to readout 0 + ) + + # Play tones 0 and 2 (mask selects which declared tones sum together) + prog.pulse(ch=0, style='const', mask=[0, 2], length=1000) + +Directly poking registers (``set_tones()``/``set_tones_int()`` on the +driver, reached as ``soc.gens[0]``) is supported for debugging but is not +the normal path -- see ``AbsMuxSignalGen.set_tones()``'s docstring: *"This +method is not normally used, it's only for debugging and testing."* Setting +the mixer frequency directly (``soc.gens[0].set_mixer_freq(f)``) is likewise +meant for constant-IQ-style outputs; for tProc-controlled generators like +this one, :meth:`.QickProgram.config_gens` calls it for you from the +``mixer_freq`` passed to ``declare_gen()``. + +-------------------------------------------------------------------- +Related Documentation +-------------------------------------------------------------------- + +* :doc:`/sg_mux8` -- the real-valued (no DAC mixer) counterpart to this IP; + read that page first for the parts of the datapath (FIFO, control FSM, + adder tree, quantization) that are shared verbatim. +* :doc:`/sg_v6` -- the arbitrary-envelope (non-muxed) signal generator, for + comparison with a different generator family. +* :doc:`topics/freq_matching` -- keeping generator and readout frequencies + (including the shared mixer frequency) consistent. +* :doc:`/readout` -- readout system overview, including the readout-side + digital mixer that this generator's frequency is often matched against. diff --git a/docs/source/sg_mux8.rst b/docs/source/sg_mux8.rst new file mode 100644 index 000000000..ab6a243e5 --- /dev/null +++ b/docs/source/sg_mux8.rst @@ -0,0 +1,335 @@ +======================================================== +Signal Generator Mux8 (axis_sg_mux8_v1) - QICK Firmware +======================================================== + +.. contents:: + :local: + :depth: 2 + +**axis_sg_mux8_v1** is a fixed-tone, 8-way multiplexed signal generator: it +plays up to 8 simultaneous, independently-configured DDS tones per channel, +as opposed to the single-tone arbitrary generators (:doc:`/sg_v6` and its +siblings) which play one tone at a time but can shape it with an arbitrary +envelope. There is no envelope memory here -- a "pulse" on this generator is +just "play some subset of the 8 pre-programmed tones for N samples". The +module lives in the ``qick`` firmware repository under +``firmware/ip/axis_sg_mux8_v1/`` and is exposed to Python through +``qick.drivers.generator.AxisSgMux8V1``. + +A related core, **axis_sg_mixmux8_v1**, adds a DAC-side digital mixer on top +of the same 8-tone architecture; it is documented separately and is not +covered further here. + +-------------------------------------------------------------------- +1. General Description +-------------------------------------------------------------------- + +``axis_sg_mux8_v1`` (top module ``axis_sg_mux8_v1.v``, core datapath +``sg_mux8.v``) instantiates 8 independent tone slots (``N_OUT = 8``, a +``localparam`` in ``sg_mux8.v`` -- not exposed as a synthesis parameter, so +changing the tone count requires editing the RTL). Each slot has its own +frequency (``PINCx_REG``), phase (``POFFx_REG``) and gain (``GAINx_REG``) +register, all configured once over AXI-Lite. Unlike a pulse on an arbitrary +generator, a "pulse" here does not carry frequency/phase/gain -- those are +static per-tone settings -- it only selects *which* of the 8 tones are +audible (an 8-bit ``mask``) and *for how many samples*, streamed in over +``s_axis`` from the tProcessor. + +Each tone slot is built from: + +* **phase_ctrl.sv** -- a phase-coherent NCO controller (see + :ref:`sgmux8-phase-coherence` below). +* ``N_DDS`` parallel instances of the Xilinx DDS Compiler IP + (``dds_compiler_0``, one phase accumulator/sine table per parallel sample + lane -- see :ref:`sgmux8-synth-params`). +* A signed 16x16 multiply against that tone's ``GAINx_REG``, applied + identically to all ``N_DDS`` parallel-lane samples of the tone. + +The 8 tones' (gain-scaled) samples are then summed lane-by-lane across all +``N_DDS`` parallel output positions and requantized back to 16 bits (see +:ref:`sgmux8-summer`) to produce the final ``m_axis`` output. + +**Compared to the mux4 generators** (``AxisSgMux4V1``/``V2``/``V3``, driver +classes in ``qick.drivers.generator``): those support only 4 simultaneous +tones rather than 8, and (for V1/V2) drive a DAC-side digital mixer +(``HAS_MIXER = True``) that this core does not have +(``AxisSgMux8V1.HAS_MIXER = False`` -- see the Python Interface section). +The mux4 RTL is out of scope for this document. + +.. _sgmux8-synth-params: + +-------------------------------------------------------------------- +2. Synthesis Parameters +-------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + :widths: 20 15 55 + + * - Parameter + - RTL Default + - Description + * - ``N_DDS`` + - 2 + - Number of parallel DDS/sample lanes per tone, i.e. how many output + samples each tone (and the final summed waveform) produces per + ``aclk`` cycle. ``m_axis_tdata`` is ``N_DDS*16`` bits wide (16 bits + per sample lane). Real board bitstreams use larger values -- e.g. the + ZCU216 tProc-v2 reference design (``firmware/projects/qick_tprocv2_216_demo``) + instantiates this core with ``N_DDS = 16``. + +The number of simultaneous tones (``N_OUT = 8``) is a fixed ``localparam`` +in ``sg_mux8.v``, not a synthesis parameter -- there is no generic to change +the tone count without editing the RTL. + +The per-tone DDS core (``dds_compiler_0``, Xilinx DDS Compiler) is +configured (per its ``.xci``) with 32-bit phase width, 16-bit output width, +``Output_Selection = Sine`` (a single real output per lane, not sin+cos), +and a fixed pipeline latency of 10 cycles. + +-------------------------------------------------------------------- +3. Datapath +-------------------------------------------------------------------- + +.. _sgmux8-phase-coherence: + +3.1 Per-Tone Frequency/Phase Generation (``phase_ctrl.sv``) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Each tone's phase is *not* computed by a simple running accumulator that +adds ``PINC`` every cycle. Instead ``phase_ctrl.sv`` keeps a free-running, +never-reset 32-bit sample counter ``cnt_n`` (incremented by ``N_DDS`` every +``aclk`` cycle) and computes each parallel lane's absolute phase directly +from it: + +.. code-block:: text + + phase[lane i] = (cnt_n + i) * PINC + POFF (mod 2^32) + +(implemented as ``pinc*cnt_n`` via a dedicated 32x32 pipelined multiplier, +``mult_32x32.v``, plus ``pinc*i`` for the within-cycle lane offset). Because +phase is recomputed from an absolute, ever-incrementing counter rather than +accumulated incrementally, the tone stays phase-coherent across +configuration changes -- there's no accumulator to reset or discontinue. + +``PINC_REG``/``POFF_REG`` updates are staged: the AXI-Lite-written values +only take effect when ``WE_REG`` is pulsed 0->1->0 (resynchronized into the +``aclk`` domain by a ``synchronizer_n``). Notably, **``GAIN_REG`` is *not* +gated by ``WE_REG``** -- in ``dds_top.v`` the gain multiplicand is a plain +continuous assignment (``assign gain = GAIN_REG;``), so a gain write takes +effect on its own timing rather than being staged together with the next +``WE_REG`` pulse like frequency/phase are. In normal driver usage (see +Python Interface) this is not observable, since ``PINCx``/``POFFx``/``GAINx`` +are all written before the single ``WE_REG`` pulse that follows -- but it is +a real asymmetry in the RTL, worth knowing if you ever write registers by +hand and expect all three to update atomically together. + +.. _sgmux8-summer: + +3.2 Gain Scaling and 8-Tone Summation (``sg_mux8.v``) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Inside ``dds_top.v``, each tone's 16-bit signed DDS sample is multiplied by +that tone's 16-bit signed gain and requantized to 16 bits (bits ``[30:15]`` +of the 32-bit product -- a Q15 scale, consistent with the driver's +``MAXV = 2**15-2`` gain convention). + +The 8 tones are masked (a disabled tone's contribution is forced to +``16'h0000``, not just zero-gained) and then summed lane-by-lane (across +each of the ``N_DDS`` parallel sample positions) through a pipelined, +3-stage binary adder tree (8 -> 4 -> 2 -> 1), growing to a 19-bit signed +intermediate to avoid overflow when all 8 tones are active simultaneously. +The final 19-bit sum is then requantized back down to 16 bits, with the +right-shift amount chosen by ``qsel`` -- the number of tones currently +enabled in the mask (a popcount of the 8 mask bits): + +.. list-table:: Output requantization shift (``sg_mux8.v``) + :header-rows: 1 + :widths: 20 20 60 + + * - Active tones (``qsel``) + - Shift applied + - Notes + * - 1 + - none (bits ``[15:0]``) + - + * - 2 + - >> 1 (bits ``[16:1]``) + - + * - 3 or 4 + - >> 2 (bits ``[17:2]``) + - Same shift for 3 and 4 tones -- not an exact per-count division. + * - 5, 6, 7, 8 (or 0) + - >> 3 (bits ``[18:3]``) + - Coarsest bucket; also the ``qsel`` default/fallback case. + +This is a coarse, power-of-two headroom scheme (not an exact +divide-by-tone-count normalization) -- e.g. 3 active tones are divided by 4, +not 3, and anywhere from 5 to 8 active tones are all divided by 8. + +3.3 Streaming Control -- Mask and Duration (``ctrl.sv``) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Frequency/phase/gain are static, slow-path AXI-Lite settings. What the +tProcessor actually streams in per pulse, over ``s_axis`` (40 bits wide, +queued in a 16-entry FIFO), is just: + +.. list-table:: S_AXIS descriptor word (40 bits, ``ctrl.sv``) + :header-rows: 1 + :widths: 20 15 65 + + * - Field + - Bits + - Description + * - ``mask`` + - ``[39:32]`` (8 bits) + - One bit per tone (bit *i* enables tone *i*). Tones not in the mask + are muted for this burst (see 3.2). + * - ``nsamp`` + - ``[31:0]`` (32 bits) + - Number of output samples (cycles) to hold this mask before the FSM + looks for the next queued descriptor. + +``ctrl.sv``'s FSM (``READ_ST -> CNT0_ST -> CNT_ST -> READ_ST``) dequeues one +descriptor, holds the output enabled (``m_axis_tvalid`` asserted, mask +applied) for ``nsamp`` cycles, then immediately starts the next queued +descriptor if the FIFO is non-empty -- so back-to-back mask/length +descriptors play with no gap between them, and the output only drops +(``en``/``m_axis_tvalid`` deasserted) once the FIFO runs dry. Several small +``latency_reg`` shift-register instances (in ``ctrl.sv``, ``dds_top.v`` and +``sg_mux8.v``) exist purely to align the ``mask``/enable control signals +with the multi-stage DDS -> multiply -> summer pipeline; this document does +not attempt to enumerate the combined end-to-end pipeline latency, since +that was not directly measured/simulated in this pass. + +In a full tProc-v2 design (verified against +``firmware/projects/qick_tprocv2_216_demo/bd_2023-1.tcl``), the tProcessor +does not drive this 40-bit format directly -- an ``sg_translator`` IP sits +between the tProc's common per-generator wave descriptor and this core's +``s_axis``, repacking it into the ``{mask, nsamp}`` format above. + +-------------------------------------------------------------------- +4. Register Map +-------------------------------------------------------------------- + +All registers are accessed through a standard 32-bit-word AXI-Lite slave +(``axi_slv.v``, 8-bit address bus, 64 x 32-bit word register file -- only +the first 25 words are used by this core). Byte offset = word index x 4. + +.. list-table:: + :header-rows: 1 + :widths: 22 12 14 52 + + * - Register + - Byte offset + - Width + - Description + * - ``PINC0_REG`` .. ``PINC7_REG`` + - 0x00 .. 0x1C + - 32 bits + - Per-tone DDS frequency tuning word (one register per tone, word + index = tone number). + * - ``POFF0_REG`` .. ``POFF7_REG`` + - 0x20 .. 0x3C + - 32 bits + - Per-tone phase offset. + * - ``GAIN0_REG`` .. ``GAIN7_REG`` + - 0x40 .. 0x5C + - 32-bit AXI-Lite slot; **only bits [15:0] reach the datapath** + - Per-tone signed gain. The AXI-Lite register itself is a full 32-bit + word (like every other register in this block's ``axi_slv``), but + the ``GAINx_REG`` ports on ``sg_mux8.v``/``dds_top.v`` are declared + only 16 bits wide, so the upper 16 bits written over AXI-Lite are + silently dropped before they reach the multiplier. This was + confirmed by reading the port declarations in ``sg_mux8.v`` and + ``dds_top.v`` (16-bit) against ``axi_slv.v`` (32-bit output ports). + * - ``WE_REG`` + - 0x60 + - 1 bit (bit 0 of a 32-bit word) + - Write-enable pulse. Toggling 0->1->0 latches the currently-written + ``PINCx``/``POFFx`` values into the phase-coherent controllers of + all 8 tones simultaneously (``GAINx`` is not gated by this bit -- + see 3.1). + +-------------------------------------------------------------------- +5. Python Interface +-------------------------------------------------------------------- + +The driver is ``qick.drivers.generator.AxisSgMux8V1`` +(``bindto = ['user.org:user:axis_sg_mux8_v1:1.0', 'QICK:QICK:axis_sg_mux8_v1:1.0']``), +a thin subclass of ``AbsMuxSignalGen`` with: + +.. code-block:: python + + HAS_MIXER = False + B_DDS = 32 + N_TONES = 8 + HAS_GAIN = True + HAS_PHASE = True + B_PHASE = 32 + +``AbsMuxSignalGen._init_config()`` builds the register-name-to-word-index +map programmatically from these flags -- ``pinc{i}_reg`` at words 0-7, +``poff{i}_reg`` at words 8-15 (since ``HAS_PHASE``), ``gain{i}_reg`` at +words 16-23 (since ``HAS_GAIN``), then ``we_reg`` at word 24 -- which +matches the RTL register map in section 4 exactly (verified by reading both +sides). + +**Normal usage** goes through :meth:`.QickProgram.declare_gen` and the +per-pulse ``mask``/``length`` parameters, not direct register access: + +.. code-block:: python + :caption: Configuring and playing tones on a mux8 generator + + from qick import * + + soc = QickSoc() + # ch = the index of the axis_sg_mux8_v1 channel in soc['gens'] + + class MyProgram(QickProgram): + def initialize(self): + # Declare up to 8 tones; unlisted mask indices play silence. + self.declare_gen(ch=ch, nqz=2, + mux_freqs=[100.0, 150.0, 220.5], # MHz + mux_gains=[1.0, 0.8, 0.5], # -1..1 + mux_phases=[0, 0, 90]) # degrees + + def body(self): + # Play tones 0 and 2 together for 1000 samples. + self.pulse(ch=ch, style='const', mask=[0, 2], length=1000) + +``declare_gen`` calls :meth:`.QickProgram.calc_muxgen_regs` to convert the +float MHz/gain/degrees values into raw ``freq_int``/``gain_int``/ +``phase_int`` register values (via :meth:`.QickProgram.freq2reg` / +:meth:`.QickProgram.deg2reg`, using ``B_DDS = 32``/``B_PHASE = 32``, and +``gain_int = round(gain * MAXV)`` with ``MAXV = 2**15-2``), which +``config_gens()`` then pushes into the generator via +``AxisSgMux8V1.set_tones_int()`` (which loops over the tones, writes +``pincX_REG``/``gainX_REG``/``poffX_REG`` for each configured tone and +zeroes the gain of any unconfigured tone up to ``N_TONES``, then pulses +``we_reg``). The pulse's ``mask``/``length`` parameters are packed by +``MultiplexedGenManager`` (``qick.asm_v1``/``qick.asm_v2``) into the +40-bit ``{mask, nsamp}`` descriptor described in section 3.3. + +.. note:: + + ``AbsMuxSignalGen.set_tones()`` (a debug-only convenience method, not + normally called by user code) calls ``self.set_all_int(tones)`` -- + but ``set_all_int`` is not defined anywhere on ``AbsMuxSignalGen`` or + its base classes (only ``set_tones_int`` is). This looks like a + leftover/typo in the current driver source (``qick_lib/qick/drivers/generator.py``) + and would raise an ``AttributeError`` if called; use + ``set_tones_int()`` directly, or the normal ``declare_gen()`` path + above, instead. + +-------------------------------------------------------------------- +Related Documentation +-------------------------------------------------------------------- + +* :doc:`/sg_v6` -- the single-tone arbitrary-envelope generator, for + contrast with this fixed-tone mux design. +* :doc:`/tprocv2_trm` -- tProcessor v2 instruction reference, including the + wave-descriptor mechanism translated by ``sg_translator`` into this core's + mask/length format. +* :doc:`/firmware` -- firmware overview and channel assignments. +* `axis_sg_mux8_v1 source code `_ diff --git a/docs/source/sg_v4.rst b/docs/source/sg_v4.rst new file mode 100644 index 000000000..af2ba274a --- /dev/null +++ b/docs/source/sg_v4.rst @@ -0,0 +1,460 @@ +======================================================== +Signal Generator v4 (SG-v4) - QICK Firmware +======================================================== + +.. contents:: + :local: + :depth: 2 + +**axis_signal_gen_v4** is QICK's original tProc-controlled arbitrary-waveform +generator: a single real-valued output lane fed by ``N_DDS`` parallel +DDS-plus-mixer channels, each pairing one complex multiplier with its own +envelope BRAM. It is the direct predecessor of :doc:`/sg_v6`, and the two +share the same Python driver class (``qick.drivers.generator.AxisSignalGen``) +-- its docstring states plainly that the class "Supports AxisSignalGen +V4+V5+V6, since they have the same software interface (ignoring registers +that are not used)". The module lives in the ``qick`` firmware repository +under ``firmware/ip/axis_signal_gen_v4/``. + +Unlike SG-v6, SG-v4 does not appear in any currently-shipped board project +in this repository (no ``firmware/Projects/**`` block-design script +instantiates ``axis_signal_gen_v4``); it is documented here as the legacy +core the Python driver still supports, and to make the concrete differences +from SG-v6 explicit for anyone reading old designs or the driver's +backward-compatibility code paths. + +-------------------------------------------------------------------- +1. General Description +-------------------------------------------------------------------- + +The core is built from four RTL blocks (``axis_signal_gen_v4.v`` instantiates +the first two; ``signal_gen_top.v`` instantiates the rest): + +* ``axi_slv`` (``axi_slv.vhd``) -- the AXI4-Lite configuration register file. +* ``signal_gen_top`` (``signal_gen_top.v``) -- wires up the waveform FIFO, + the envelope-loading state machine, the per-lane BRAMs, and the + ``signal_gen`` core. +* ``data_writer`` (``data_writer.vhd``) -- an FSM that streams envelope + samples from ``s0_axis`` into the interleaved per-lane BRAMs. +* ``signal_gen`` (``signal_gen.v``, with ``ctrl.sv`` as its descriptor-decode + FSM) -- reads queued waveform descriptors, drives ``N_DDS`` parallel + ``dds_compiler_0`` instances, multiplies each against its envelope sample, + and muxes/rounds the result onto ``m_axis``. + +``AxisSignalGen.HAS_MIXER = False`` in the Python driver: there is no +DAC-side digital mixer downstream of this block (unlike the interpolated +``axis_sg_int4_v*`` generators) -- all upconversion is done by the per-lane +DDS itself, which is why :meth:`.QickProgram.declare_gen` never asks for a +``mixer_freq`` on this channel. + +Two source files in ``firmware/ip/axis_signal_gen_v4/src/`` -- ``dither.v`` +and ``random_gen.v`` -- are **not part of the active datapath**; see +:ref:`sgv4-dithering` below. + +-------------------------------------------------------------------- +2. Synthesis Parameters +-------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + :widths: 20 15 55 + + * - Parameter + - RTL Default + - Description + * - ``N`` + - 12 + - Envelope memory address width. Each of the ``N_DDS`` lanes owns a + real-part BRAM and an imaginary-part BRAM, each ``2**N`` samples + deep x 16 bits wide. With the default, that's 4096 samples/lane, + 65536 samples total across the interleaved lanes -- this is what the + Python driver reports as ``cfg['maxlen']`` (``2**N * N_DDS``, in + ``AxisSignalGen._init_config``). SG-v6's top-level default for the + same parameter is ``N = 16`` (see :doc:`/sg_v6`); the value actually + burned into a given bitstream depends on how the block design + instantiated the core, so read ``soc.gens[i]['maxlen']`` at runtime + rather than assuming either default. + * - ``N_DDS`` + - 16 + - Number of parallel DDS + complex-multiplier lanes, and therefore + samples emitted per ``aclk`` cycle on ``m_axis_tdata`` (bus width + ``N_DDS * 16`` bits). Exposed to Python as ``SAMPS_PER_CLK = 16`` on + the driver class. + +SG-v4 has no ``GEN_DDS`` or ``ENVELOPE_TYPE`` synthesis parameters -- +``axis_signal_gen_v4.v`` declares only ``N`` and ``N_DDS``. Both DDS lanes +and imaginary-part BRAMs are therefore always present; there is no +baseband-only or real-only-envelope build option (both were added in +SG-v6 -- see :ref:`sgv4-vs-sgv6`). Correspondingly, +``AbsPulsedSignalGen._init_config`` falls back to the class default +``HAS_DDS = True`` and ``AbsArbSignalGen._init_config`` falls back to +``COMPLEX_ENVELOPE = True`` for this core, since neither ``GEN_DDS`` nor +``ENVELOPE_TYPE`` is present in its parameter dict. + +-------------------------------------------------------------------- +3. Datapath +-------------------------------------------------------------------- + +3.1 Waveform descriptor queue (``s1_axis``) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``s1_axis_tdata`` is a 160-bit waveform descriptor, pushed straight into a +16-entry, 160-bit-wide FIFO (``fifo.vhd``, ``.B(160)``, ``.N(16)``) with +``fifo_wr_en = s1_axis_tvalid`` and ``s1_axis_tready = ~fifo_full`` -- there +is no register staging on the write side, unlike ``axis_readout_v2``'s +``WE_REG``-pulsed descriptor push (:doc:`/readout_v2`). ``ctrl.sv`` decodes +the descriptor at the head of the FIFO: + +.. list-table:: Waveform descriptor fields (``ctrl.sv`` header comment) + :header-rows: 1 + :widths: 15 15 15 55 + + * - Field + - Bits + - Width + - Description + * - ``freq`` + - ``[31:0]`` + - 32 + - DDS frequency tuning word for this pulse. + * - ``phase`` + - ``[63:32]`` + - 32 + - DDS phase offset for this pulse. + * - ``addr`` + - ``[79:64]`` + - 16 + - Envelope-memory start address to read for this pulse (**not** the + same register as ``START_ADDR_REG`` below -- that one is only used + when bulk-loading samples over ``s0_axis``). + * - ``gain`` + - ``[111:96]`` + - 16 + - Signed output gain. + * - ``nsamp`` + - ``[143:128]`` + - 16 + - Number of ``aclk`` cycles (each emitting ``N_DDS`` samples) to stay + in the active ``CNT_ST`` state before returning to ``READ_ST``. + * - ``outsel`` + - ``[145:144]`` + - 2 + - Per-pulse output-source select: 0 = product (DDS x envelope), 1 = + DDS only, 2 = envelope only, 3 = zero. **Not the same control as the + ``OUTSEL_REG`` AXI register** described in :ref:`sgv4-regmap` -- + despite the similar name, that register picks the real/imaginary + component of whatever this field selects, chip-wide, not per pulse. + * - ``mode`` + - ``146`` + - 1 + - 0: play for ``nsamp`` cycles and stop. 1: play continuously + (periodic). + * - ``stdysel`` + - ``147`` + - 1 + - Steady-value select; see :ref:`sgv4-steady` below. + * - ``phrst`` + - ``148`` + - 1 + - Documented in the header comment table but **not read anywhere in + ``ctrl.sv``'s body** -- ``fifo_dout_r[148]`` is never referenced. + Setting this bit has no effect in SG-v4. SG-v6's ``ctrl_sg_v6.sv`` + *does* wire the equivalent bit (``phrst_int = fifo_dout_r[148]``) + into a synchronous phase-accumulator reset -- see + :ref:`sgv4-vs-sgv6`. + +The FSM (``READ_ST`` / ``CNT_ST``) reads a new descriptor whenever it's idle +and the FIFO isn't empty (or ``mode`` is periodic), then holds in +``CNT_ST`` for ``nsamp`` cycles. ``gain``, the 2-bit ``src`` (outsel), +``stdysel``, and the enable flag are each pushed through long shift-register +pipelines (4 stages inside ``ctrl.sv``, then a further 13-19 stages inside +``signal_gen.v``) to stay aligned with the DDS and multiplier latency before +they reach the output mux. + +3.2 Envelope loading (``s0_axis``) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``data_writer`` (``data_writer.vhd``) is a small FSM +(``INIT -> READ_START_ADDR -> WAIT_TVALID -> RW_TDATA``) that writes +32-bit samples arriving on ``s0_axis_tdata`` (bits ``[15:0]`` = real, +``[31:16]`` = imaginary) into the per-lane BRAM pair. It keeps one flat +running address (``mem_addr_full``); the low ``ceil(log2(N_DDS))`` = 4 bits +select which of the ``N_DDS`` lanes' ``mem_ena`` to assert, and the +remaining ``N`` bits become that lane's BRAM address -- i.e. samples are +written round-robin across the 16 lanes. ``WE_REG`` is resynchronized into +the ``s0_axis_aclk`` domain with a 2-stage ``synchronizer_n`` before it can +move the FSM out of ``INIT``, and the counter is reloaded from +``START_ADDR_REG`` each time a new write burst starts. + +Each lane's real and imaginary BRAMs are separate ``bram_dp`` instances +(the shared dual-port BRAM primitive under ``firmware/hdl/``, not the +single-port ``bram.v`` file that ships in this IP's own ``src/`` -- that +file is unused, see :ref:`sgv4-dithering`). Write port A runs on +``s0_axis_aclk``; read port B runs on ``aclk`` and is driven by +``signal_gen``. + +3.3 Per-lane DDS and complex multiply +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Each of the ``N_DDS`` lanes instantiates its own ``dds_compiler_0`` core, +phase-offset from its neighbors by ``pinc * i`` (lane ``i`` represents time +step ``i`` within the current ``N_DDS``-wide parallel block, so the 16 +lanes together form one coherent, phase-continuous tone). ``signal_gen.v`` +then computes the **full complex product** of the DDS output (I, Q) against +the envelope sample (I, Q) read back from BRAM: + +.. code-block:: text + + prod_real = dds_I * env_I - dds_Q * env_Q + prod_imag = dds_I * env_Q + dds_Q * env_I + +That's four 16x16 multiplies per lane, even though (per +:ref:`sgv4-outsel-note` below) only one of ``prod_real``/``prod_imag`` is +ever driven onto the output. SG-v6 removed the two multiplies needed for +``prod_imag`` entirely, since it never produces a usable imaginary output +(see :ref:`sgv4-vs-sgv6`). + +.. _sgv4-outsel-note: + +3.4 Output source mux, real/imag select, and rounding +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``dout_mux[i]`` picks one 32-bit ``{imag, real}`` word per the per-pulse +``outsel`` descriptor field (product / DDS-only / envelope-only / zero, +see 3.1), and that word is scaled by ``gain`` (one more signed 16x16 +multiply) and rounded (bits ``[30:15]`` of the 32-bit gained product, i.e. +truncation after the gain multiply, no separate rounding-add term). The +final 16-bit sample driven onto ``m_axis_tdata[i*16 +: 16]`` picks between +the rounded real and imaginary halves using **``OUTSEL_REG``**, a +chip-wide AXI-Lite register (0 = real, 1 = imaginary) -- *not* the +per-pulse ``outsel`` descriptor field. Because ``m_axis_tdata`` only +carries one 16-bit sample per lane per cycle (not a 32-bit I/Q pair), a +single generator instance can only ever emit the real *or* the imaginary +component of its internal complex datapath, chosen once for the whole +core via this register, not per pulse. + +.. _sgv4-steady: + +3.5 Enable / steady-value gating +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``m_axis_tdata[i] = (~en & stdysel) ? 0 : round_r_mux[i]``. When the +generator is disabled (between pulses, or after a one-shot ``mode=0`` +pulse finishes) and ``stdysel`` is set, the output is forced to zero; +otherwise the (possibly stale, still-pipelined) ``round_r_mux`` value +passes through unchanged. SG-v4 has no dedicated "hold the last sample" +state -- see :ref:`sgv4-vs-sgv6` for how SG-v6 differs here. + +.. _sgv4-dithering: + +3.6 Dithering RTL is present but disconnected +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``firmware/ip/axis_signal_gen_v4/src/`` contains ``dither.v`` (adds +LFSR-generated pseudo-random noise, scaled by a register-controlled shift +amount, ahead of a bit-truncation -- a standard dithering-before-requantize +technique) and ``random_gen.v`` (a parameterizable-width Fibonacci-tap +LFSR). Neither module is instantiated anywhere in +``signal_gen_top.v``/``signal_gen.v``; the only place ``dither`` is +referenced is inside its own file, instantiating ``random_gen``. The +``RNDQ_REG`` register (see :ref:`sgv4-regmap`) is wired all the way from +``axi_slv`` down through ``signal_gen_top`` into ``signal_gen.v``'s port +list, but ``signal_gen.v``'s body never reads it. This is corroborated on +the Python side: ``AxisSignalGen.rndq()`` is annotated +``"TODO: remove this function. This functionality was removed from IP +block."``, and the register is set once to a placeholder value (``10``) in +``_init_firmware`` and never touched again. Treat SG-v4's dithering support +as vestigial source code, not a working feature. (A separate, +independently-maintained register-description package in this repo, +``firmware/fusesoc/cores/ip/axis_signal_gen_v4/rdl/``, describes +``RNDQ_REG`` the same way: "Deprecated (rounding-select removed). Retained +as a dummy for register-map / driver bindto compatibility (no functional +effect)" -- consistent with what the RTL shows, though that package +describes a different, non-synthesized register model and should not be +read as documenting this IP's actual register file.) + +.. _sgv4-regmap: + +-------------------------------------------------------------------- +4. Register Map +-------------------------------------------------------------------- + +``axi_slv.vhd`` implements a generic 16-register, 6-bit-address AXI4-Lite +block (word-addressed offsets ``0x00``-``0x3C``), but only wires the first +four registers to anything; the remaining twelve are plain, unconnected +flip-flops (writable and readable, but with no effect on the datapath). + +.. list-table:: + :header-rows: 1 + :widths: 22 12 15 51 + + * - Register + - Offset + - Width + - Description + * - ``START_ADDR_REG`` + - ``0x00`` + - 32 bits + - Flat start address (lane-interleaved) for the next bulk envelope + write over ``s0_axis``. Loaded into ``data_writer``'s address + counter when ``WE_REG`` rises. + * - ``WE_REG`` + - ``0x04`` + - 1 bit (``slv_reg1[0]``) + - Envelope-memory write enable. Level-sensitive, resynchronized into + the ``s0_axis_aclk`` domain. + * - ``RNDQ_REG`` + - ``0x08`` + - 32 bits + - Comment in ``axi_slv.vhd``: "Noise amplitude for dithering." Not + actually connected to any dithering logic -- see + :ref:`sgv4-dithering`. + * - ``OUTSEL_REG`` + - ``0x0C`` + - 1 bit (``slv_reg3[0]``) + - Chip-wide real/imaginary output select (0 = real, 1 = imaginary); + see :ref:`sgv4-outsel-note`. **Not present in the Python driver's + ``REGISTERS`` dict** (``AxisSignalGen.REGISTERS = {'start_addr_reg': + 0, 'we_reg': 1, 'rndq_reg': 2}``), so it can't be written from + Python -- it stays at its post-reset value, which is ``0`` (real + component) since all ``slv_reg`` are cleared to zero on + ``aresetn``. + +All registers are simple ``std_logic_vector`` flops written a full 32 bits +at a time (byte-strobed) on the ``s_axi_aclk`` domain; there is no +write-pulse/handshake semantics beyond the level of ``WE_REG`` itself. + +.. _sgv4-vs-sgv6: + +-------------------------------------------------------------------- +5. Differences from SG-v6 +-------------------------------------------------------------------- + +The two cores share a Python driver and a wire-compatible 160-bit +descriptor format, but the RTL differs in several concrete ways: + +.. list-table:: + :header-rows: 1 + :widths: 30 35 35 + + * - Aspect + - SG-v4 + - SG-v6 + * - Complex product + - Computes both real and imaginary parts of DDS x envelope (4 + multiplies/lane); only one is ever output. + - Computes only the real part (2 multiplies/lane); the imaginary + partial products are commented out of ``signal_gen.v`` entirely. + * - Real/imag output select + - Chip-wide ``OUTSEL_REG`` AXI register (not exposed by the Python + driver). + - Removed -- ``axi_slv_sg_v6.vhd`` only implements + ``START_ADDR_REG``/``WE_REG``. + * - Baseband-only mode + - Not available -- DDS lanes are always instantiated. + - ``GEN_DDS = "FALSE"`` synthesis parameter removes the DDS + compilers, for baseband-envelope-only builds. + * - Real-only envelope + - Not available -- both real and imaginary BRAMs are always + instantiated per lane. + - ``ENVELOPE_TYPE = "REAL"`` synthesis parameter drops the imaginary + BRAM and forces ``mem_dob_imag`` to zero. + * - ``phrst`` descriptor bit + - Defined in the descriptor format comment (bit 148) but never read + in ``ctrl.sv``. No effect. + - Read (``phrst_int = fifo_dout_r[148]``) and used to reset the phase + accumulator synchronously with a new descriptor load. + * - Dithering + - ``dither.v``/``random_gen.v`` present in ``src/`` but not + instantiated; ``RNDQ_REG`` exists but is unconnected. Vestigial. + - Files and register removed entirely. + * - Idle/steady output + - Forces output to zero when disabled and ``stdysel`` is set; + otherwise the last pipelined value passes through as-is (no + explicit hold). + - Adds an explicit ``last_r`` register that latches the final sample + whenever enabled, so the idle output can hold that value + (``stdysel=0``) or force zero (``stdysel=1``). + * - Register pipelining style + - Manually chained ``reg`` stages (``_r1``, ``_r2``, ... up to + ``_r19`` in places). + - A reusable parameterized ``latency_reg`` module for each delay + line. + * - Top-level ``N`` default + - 12 (4096 samples/lane). + - 16 (65536 samples/lane). + +From a QICK-program-writer's point of view these are resource/feature +differences, not API differences: both bind to the same +``qick.drivers.generator.AxisSignalGen`` class +(``bindto = ['user.org:user:axis_signal_gen_v4:1.0', ... +'axis_signal_gen_v6:1.0', ...]``), so :meth:`.QickProgram.declare_gen`, +:meth:`.QickProgram.add_envelope`, and pulse-playback instructions work +identically on either version -- you simply lose the ability to select the +imaginary output, use per-pulse phase reset, or run in baseband/real-only +modes on SG-v4. + +-------------------------------------------------------------------- +6. Python Interface +-------------------------------------------------------------------- + +SG-v4 is reached through the same class hierarchy as every other QICK +pulsed generator (``qick.drivers.generator``): + +* ``AbsSignalGen`` -- ``MAXV = 2**15-2``; Nyquist-zone and (if + ``HAS_MIXER``) mixer-frequency helpers. +* ``AbsArbSignalGen(AbsSignalGen)`` -- adds the envelope DMA path + (``load()``, over ``s0_axis``) and ``_wr_enable``/``_wr_disable`` + (``START_ADDR_REG``/``WE_REG``). +* ``AbsPulsedSignalGen(AbsSignalGen)`` -- adds the tProc-facing ``s1_axis`` + port and DDS/phase width config (``B_DDS``, ``B_PHASE``, ``HAS_DDS``). +* ``AxisSignalGen(AbsArbSignalGen, AbsPulsedSignalGen)`` -- the concrete + class, with ``bindto`` covering the v4/v5/v6 IP-core VLNV strings, + ``HAS_MIXER = False``, ``SAMPS_PER_CLK = 16``, ``B_DDS = B_PHASE = 32``. + +Because ``ENVELOPE_TYPE``/``GEN_DDS`` aren't present in SG-v4's synthesis +parameters, ``cfg['complex_env']`` and ``cfg['has_dds']`` fall back to the +class defaults (``True``/``True``) for this core. + +Most QICK programs never touch this driver directly -- pulses are declared +through :meth:`.QickProgram.declare_gen` and +:meth:`.QickProgram.add_envelope`/:meth:`.QickProgram.add_gauss`, and +played via the normal tProc pulse instructions, exactly as for SG-v6. The +one thing worth calling out for SG-v4 specifically is that ``OUTSEL_REG`` +is not reachable from Python (see :ref:`sgv4-regmap`): if you need the +imaginary component of the DDS x envelope product out of an SG-v4 +channel, there is no driver method for it -- you would have to write the +register through the low-level MMIO interface yourself. + +.. code-block:: python + :caption: Loading an envelope and playing an SG-v4 pulse + + from qick import * + import numpy as np + + soc = QickSoc() + gen_ch = 0 # an SG-v4 channel on this board + + soc.declare_gen(ch=gen_ch, nqz=1) # no mixer_freq: HAS_MIXER is False + + # Gaussian envelope, real part only (imaginary defaults to zero if omitted) + length = 100 + sigma = length / 5 + idata = 30000 * np.exp(-0.5 * ((np.arange(length) - length/2) / sigma)**2) + soc.add_envelope(ch=gen_ch, name="gauss", idata=idata.astype(np.int16)) + + soc.set_pulse_registers(ch=gen_ch, style="arb", envelope="gauss", + freq=soc.freq2reg(100.0, gen_ch=gen_ch), + phase=0, gain=30000, length=length) + +-------------------------------------------------------------------- +Related Documentation +-------------------------------------------------------------------- + +* :doc:`/sg_v6` -- the successor core; see :ref:`sgv4-vs-sgv6` above for + the concrete RTL differences. +* :doc:`/tprocv2_trm` -- tProcessor sequencing/triggering that queues + waveform descriptors into this core's ``s1_axis``. +* :doc:`/firmware` -- firmware overview and channel assignments. +* :doc:`/readout_v2` -- a similarly-legacy, single-tone predecessor core on + the readout (ADC) side, for comparison. diff --git a/docs/source/sg_v6.rst b/docs/source/sg_v6.rst new file mode 100644 index 000000000..c8d911d7f --- /dev/null +++ b/docs/source/sg_v6.rst @@ -0,0 +1,504 @@ +======================================================== +Signal Generator v6 (SG-v6) - QICK Firmware +======================================================== + +.. contents:: + :local: + :depth: 2 + +The **Signal Generator v6** (SG-v6) is the newest version of QICK's +on-chip waveform engine. It supersedes SG-v5 with a richer feature set, +lower latency, and full compatibility with all QICK-compatible boards +(ZCU216, ZCU111, etc.). The module lives in the ``qick`` firmware +repository under ``firmware/ip/axis_signal_gen_v6/`` and is exposed to Python +through the ``qick.drivers.generator`` class. + +-------------------------------------------------------------------- +1. General Description +-------------------------------------------------------------------- + +The **Signal Generator v6 (SG-v6)** is the QICK waveform generation module +implemented in the ``signal_gen_top`` firmware entity. Its architecture combines: + +* A **dual-port memory (BRAM)** to store envelope samples. +* A **FIFO** to queue 160-bit waveform descriptors. +* A central ``signal_gen`` block that reads the FIFO, accesses memory, and generates + the output through N parallel DDS channels. + +The module supports two synthesis-configurable operating modes: + +* **DDS Mode** (``GEN_DDS = "TRUE"``): generates complex tones with upconversion. +* **Baseband Mode** (``GEN_DDS = "FALSE"``): outputs only the envelope, without DDS. + +And two envelope types: + +* **COMPLEX** (``ENVELOPE_TYPE = "COMPLEX"``): separate memories for real and imaginary parts. +* **REAL** (``ENVELOPE_TYPE = "REAL"``): real part only; the imaginary part is forced to zero. + +-------------------------------------------------------------------- +2. Synthesis Parameters +-------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + :widths: 20 15 55 + + * - Parameter + - Default Value + - Description + * - ``N`` + - 16 + - Memory address bus size (number of bits). The effective table depth + is **2^N** samples per bank. + * - ``N_DDS`` + - 16 + - Number of parallel DDS blocks and, therefore, samples emitted per clock + cycle on the ``m_axis_tdata_o`` output bus (total width = ``N_DDS × 16`` bits). + * - ``GEN_DDS`` + - ``"TRUE"`` + - ``"TRUE"`` instantiates DDS blocks for upconversion. ``"FALSE"`` generates only + the baseband envelope. + * - ``ENVELOPE_TYPE`` + - ``"COMPLEX"`` + - ``"COMPLEX"`` instantiates separate BRAMs for real and imaginary parts. ``"REAL"`` + uses only the real BRAM and assigns zero to the imaginary part. + +-------------------------------------------------------------------- +3. Interface Ports +-------------------------------------------------------------------- + +3.1 Clock and Reset +^^^^^^^^^^^^^^^^^^^ + +.. list-table:: + :header-rows: 1 + :widths: 30 10 50 + + * - Signal + - Direction + - Description + * - ``aresetn`` + - input + - Active-low reset for the main clock domain (``aclk``). + * - ``aclk`` + - input + - Main clock. Drives the FIFO, the ``signal_gen`` block, and the output bus. + +3.2 S0_AXIS – Envelope Sample Loading +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Slave AXI-Stream interface to transfer envelope samples to the internal BRAM. +It operates in the ``s0_axis_aclk`` domain, which can be different from ``aclk``. + +.. list-table:: + :header-rows: 1 + :widths: 30 10 10 50 + + * - Signal + - Direction + - Width + - Description + * - ``s0_axis_aresetn`` + - input + - 1 + - Active-low reset for the S0 domain. + * - ``s0_axis_aclk`` + - input + - 1 + - S0 domain clock. Can differ from ``aclk`` (dual-clock BRAM). + * - ``s0_axis_tdata_i`` + - input + - 32 + - Sample data. Bits [15:0] = real part; bits [31:16] = imaginary part + (only written if ``ENVELOPE_TYPE = "COMPLEX"``). + * - ``s0_axis_tvalid_i`` + - input + - 1 + - Indicates valid data on the bus (standard AXI-Stream protocol). + * - ``s0_axis_tready_o`` + - output + - 1 + - Module indicates availability to receive data. + +3.3 S1_AXIS – Waveform Queue +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Slave AXI-Stream interface to queue **160-bit** waveform descriptors. +Each descriptor defines the parameters for a playback burst. + +.. list-table:: + :header-rows: 1 + :widths: 30 10 10 50 + + * - Signal + - Direction + - Width + - Description + * - ``s1_axis_tdata_i`` + - input + - 160 + - 160-bit waveform descriptor. The ``signal_gen`` block interprets its + content internally. + * - ``s1_axis_tvalid_i`` + - input + - 1 + - Indicates a valid descriptor. Connected directly to ``fifo_wr_en``. + * - ``s1_axis_tready_o`` + - output + - 1 + - Asserted when the internal FIFO is not full (``~fifo_full``). + +3.4 M_AXIS – Data Output +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Master AXI-Stream interface that delivers generated samples to the DAC or the +next block in the datapath. + +.. list-table:: + :header-rows: 1 + :widths: 30 10 10 50 + + * - Signal + - Direction + - Width + - Description + * - ``m_axis_tready_i`` + - input + - 1 + - Consumer indicates it can accept data. + * - ``m_axis_tvalid_o`` + - output + - 1 + - Module indicates that ``m_axis_tdata_o`` contains valid data. + * - ``m_axis_tdata_o`` + - output + - ``N_DDS × 16`` + - Output sample bus. With default values (``N_DDS = 16``), the width is + **256 bits**, corresponding to 16 samples of 16 bits per cycle. + +3.5 Control Registers +^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: + :header-rows: 1 + :widths: 30 10 10 50 + + * - Signal + - Direction + - Width + - Description + * - ``START_ADDR_REG`` + - input + - 32 + - Starting address in BRAM where the ``data_writer`` will begin writing + samples received via S0_AXIS. + * - ``WE_REG`` + - input + - 1 + - BRAM write enable. When asserted, the ``data_writer`` propagates the + write to the selected BRAM. + +-------------------------------------------------------------------- +4. Internal Architecture +-------------------------------------------------------------------- + +The ``signal_gen_top`` module instantiates and connects four main blocks: + +4.1 FIFO (``fifo_xpm``) +^^^^^^^^^^^^^^^^^^^^^^^ + +* Data width: **160 bits**. +* Depth: **16 entries**. +* Writing occurs directly from S1_AXIS (``fifo_wr_en = s1_axis_tvalid_i``). +* The ``fifo_full`` flag controls the ``s1_axis_tready_o`` signal (backpressure). +* The ``signal_gen`` block manages reading (``fifo_rd_en``). + +4.2 Data Writer (``data_writer``) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Receives samples via S0_AXIS and writes them to the correct BRAM according to the +``START_ADDR_REG`` and ``WE_REG`` registers. It generates bank enable signals +(``mem_ena``, an ``N_DDS``-bit vector), address (``mem_addra``), and data (``mem_dia``). + +4.3 BRAM Memories (``bram_dp_xpm``) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +**N_DDS** BRAM instances are generated (one per DDS channel), each **16 bits wide** +and **2^N** positions deep. + +* **Port A (Write):** ``s0_axis_aclk`` domain. Receives data from the ``data_writer``. +* **Port B (Read):** ``aclk`` domain. The ``signal_gen`` provides the address + ``mem_addrb`` and receives data in parallel. + +If ``ENVELOPE_TYPE = "COMPLEX"``, a second BRAM per channel is instantiated for +the imaginary part (data in bits [31:16] of the S0 bus). If ``ENVELOPE_TYPE = "REAL"``, +the ``mem_dob_imag`` signal is forced to zero. + +.. note:: + + Both BRAMs (real and imaginary) of a channel share the same read address + ``mem_addrb`` and enable pin ``mem_ena[i]``, ensuring coherence between + real and imaginary parts. + +4.4 Signal Generator (``signal_gen``) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The core of the module. It reads descriptors from the FIFO, generates memory +addresses, and produces output samples by combining the envelope read from BRAM +with the DDS blocks. The ``GEN_DDS`` parameter controls whether internal DDS +blocks are instantiated. + +-------------------------------------------------------------------- +5. Data Flow Diagram +-------------------------------------------------------------------- + +:: + + S0_AXIS ──► data_writer ──► BRAM_real[0..N_DDS-1] ──┐ + BRAM_imag[0..N_DDS-1] ──┤ + ▼ + S1_AXIS ──► fifo_xpm ──────────────────────────► signal_gen ──► M_AXIS + (+ DDS if GEN_DDS=TRUE) + + Registers: START_ADDR_REG, WE_REG ──► data_writer + +-------------------------------------------------------------------- +6. Python Usage (QICK) +-------------------------------------------------------------------- + +.. note:: + + Earlier revisions of this section showed a direct-register API + (``gen.set_freq()``, ``gen.load_waveform()``, ``tproc.load_wave()``, raw + ``WPORT_WR`` assembly) that does not match the current ``qick_lib`` + driver/assembler -- there is no ``qick.SignalGenerator`` class, and none + of those methods exist on the actual generator driver + (``qick.drivers.generator.AxisSignalGen``). The workflow below was + verified against ``qick.qick_asm``/``qick.asm_v2`` in this repository. + +``soc.gens[i]`` gives you the low-level driver for generator array index +``i`` -- this is the same ``i`` you pass to ``declare_gen(ch=i, ...)`` and +``add_pulse(ch=i, ...)``, and the same index :class:`.QickProgram` code +always uses. It is **not** simply "tProc channel - 1": which tProc +waveform port and DAC each array index maps to is board-specific and, on +some boards, not a 1:1 mapping at all (see the worked ZCU216 example in +:doc:`/firmware`'s :ref:`tproc-zcu216-example`). Normal programs never need +to know this mapping -- declare the channel once by its ``soc.gens[]`` +index, register any envelopes, add named pulses, then play them by name at +whatever time you choose. + +6.1. Basic Configuration and Immediate Playback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A ``const`` pulse needs no envelope -- the DDS output is gated on for +``length`` at a fixed ``gain``. + +.. code-block:: python + :caption: Basic SG-v6 pulse from Python + + from qick import * + + soc = QickSoc() + + class BasicPulse(AveragerProgramV2): + def _initialize(self, cfg): + # gen array index 0 -- see /firmware for how this maps to a + # DAC on your specific board + self.declare_gen(ch=0, nqz=1) + self.add_pulse(ch=0, name="tone", style="const", + freq=100.0, phase=0, gain=0.5, length=1.0) # MHz, deg, -1..1, us + + def _body(self, cfg): + self.pulse(ch=0, name="tone", t=0) + + prog = BasicPulse(soccfg, reps=1, final_delay=1.0, cfg={}) + prog.acquire(soc) # no readouts declared -> just runs the pulse once per rep + +6.2. Playing a Shaped Pulse with an Envelope +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Shaped pulses (Gaussian, DRAG, etc.) go through +:meth:`.QickProgram.add_envelope` -- the I/Q samples are uploaded to the +generator's internal BRAM once, and referenced by name from any number of +``arb`` (or ``flat_top``) pulses. ``add_envelope`` handles the +``w_env``/length bookkeeping for you. + +.. code-block:: python + :caption: Shaped pulse with a Gaussian envelope + + from qick import * + import numpy as np + + soc = QickSoc() + + class GaussianPulse(AveragerProgramV2): + def _initialize(self, cfg): + self.declare_gen(ch=0, nqz=1) + + n_samples = 1024 + sigma = n_samples / 6 + idata = 30000 * np.exp(-0.5 * ((np.arange(n_samples) - n_samples/2) / sigma)**2) + self.add_envelope(ch=0, name="gauss", idata=idata.astype(np.int16)) + + self.add_pulse(ch=0, name="shaped", style="arb", + freq=100.0, phase=0, gain=0.9, envelope="gauss") + + def _body(self, cfg): + self.pulse(ch=0, name="shaped", t=0) + + prog = GaussianPulse(soccfg, reps=1, final_delay=1.0, cfg={}) + prog.acquire(soc) + +6.3. Multiple Pulses and the SG-v6 FIFO +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The SG-v6 can queue up to **16 waveform descriptors** in hardware (see +"FIFO Capacity" under §7 below); in software you just call :meth:`.QickProgram.pulse` +multiple times with different (or repeated) pulse names and times -- the +compiler emits one ``WPORT_WR`` per call, and the SG-v6's own FIFO/playback +logic handles queuing and back-to-back timing. + +.. code-block:: python + :caption: Queueing several pulses on the same channel + + class MultiPulse(AveragerProgramV2): + def _initialize(self, cfg): + self.declare_gen(ch=0, nqz=1) + self.add_pulse(ch=0, name="long", style="const", + freq=100.0, phase=0, gain=0.5, length=2.0) + self.add_pulse(ch=0, name="short", style="const", + freq=105.0, phase=0, gain=0.5, length=0.5) + + def _body(self, cfg): + self.pulse(ch=0, name="long", t=0) + self.pulse(ch=0, name="short", t=3.0) # us, relative to this shot's t=0 + +6.4. Descriptor Fields Reference +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The 168-bit ``r_wave`` bus (written via ``WPORT_WR``) contains six fields. +When using the tProcessor, these fields are written individually via ``w_freq``, +``w_phase``, etc., or as a group via ``r_wave``. + +.. list-table:: SG-v6 Descriptor Fields (r_wave composition) + :header-rows: 1 + :widths: 15 20 15 50 + + * - Field + - Register + - Bits + - Description + * - Frequency + - ``w_freq`` + - 32 + - DDS frequency control word (0 = DC, 2^31 = Nyquist) + * - Phase + - ``w_phase`` + - 32 + - DDS phase offset (2^32 = 360°) + * - Gain + - ``w_gain`` + - 32 + - Amplitude scaling (signed 32-bit, max 2^31-1) + * - Envelope Start + - ``w_env`` + - 24 + - Start address in envelope memory (for shaped pulses) + * - Length + - ``w_length`` + - 32 + - Number of samples to output (for shaped pulses) + * - Configuration + - ``w_conf`` + - 16 + - Mode, output selection, etc. (see SG-v6 source) + +.. note:: + + The 160-bit descriptor sent via S1_AXIS is packed internally by + :meth:`.Waveform.compile` (``qick.asm_v2``) from the fields you pass to + :meth:`.QickProgram.add_pulse`/:meth:`.QickProgram.add_envelope` -- you + don't need to build it by hand. + +6.5. Additional Resources +^^^^^^^^^^^^^^^^^^^^^^^^^ + +For more examples (multi-channel playback, real-time frequency hopping, +envelope chaining, advanced tProc sequencing), refer to: + +- **QICK Tutorial Notebooks**: :doc:`/tutorials/06_Generators_And_Readouts`, + :doc:`/tutorials/07_Advanced_Generators_And_Readouts` +- **tProcessor Documentation**: :doc:`/tprocv2_trm` +- **Firmware Overview**: :doc:`/firmware` +- **Community Examples**: Check the `#qick` channel on the Unitary Fund Discord + +-------------------------------------------------------------------- +7. Implementation Considerations +-------------------------------------------------------------------- + +**Clock Domains:** + The module contains two clock domains (``s0_axis_aclk`` and ``aclk``). Domain + crossing is resolved via dual-clock BRAMs. Ensure appropriate timing constraints + are applied in the XDC file. + +**BRAM Read Latency:** + The ``bram_dp_xpm`` instances have ``OUT_REG_ENA = 1``, adding one cycle + of latency to the read port to improve timing. + +**Output Bus Width:** + The ``m_axis_tdata_o`` bus is ``N_DDS × 16`` bits wide. With the default + ``N_DDS = 16``, this equals **256 bits** (32 bytes) per transaction. + +**Memory Depth:** + With parameter ``N = 16``, each BRAM has **65,536 positions** of 16 bits, + equivalent to **128 KB** per bank (real or imaginary). + +**FIFO Capacity:** + The waveform FIFO has a capacity for **16 descriptors** of 160 bits. + If the producer is faster than the consumer, the ``s1_axis_tready_o`` + signal must be managed. + +-------------------------------------------------------------------- +8. Default Parameters – Quick Summary +-------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Configuration + - Value + * - Samples per cycle (M_AXIS) + - 16 (``N_DDS = 16``) + * - Output bus width + - 256 bits + * - Table depth per bank + - 65,536 samples (``N = 16``) + * - FIFO capacity + - 16 descriptors of 160 bits + * - Envelope type + - Complex (I + Q) + * - DDS Mode + - Enabled (upconversion) + +-------------------------------------------------------------------- +9. Relevant Source Files +-------------------------------------------------------------------- + +* ``signal_gen_top.v`` – Top module described in this document. +* ``signal_gen.v`` – DDS core and playback logic. +* ``data_writer.v`` – BRAM sample writing from AXI-Stream. +* ``fifo_xpm.v`` – Parameterizable FIFO based on Xilinx XPM primitives. +* ``bram_dp_xpm.v`` – Parameterizable dual-port BRAM (Xilinx XPM). + +-------------------------------------------------------------------- +Related Documentation +-------------------------------------------------------------------- + +* :doc:`/generators` - overview of all QICK signal generator types and when to use each +* :doc:`/tprocv2_trm` - tProcessor v2 for sequencing and triggering +* :doc:`/firmware` - Firmware overview and channel assignments +* :doc:`/sg_mux8`, :doc:`/sg_mixmux8` - multi-tone generators, for playing several simultaneous fixed tones instead of one arbitrary-envelope pulse +* :doc:`/sg_int4_v2` - a lighter single-tone arbitrary generator (see :doc:`/generators` for the tradeoffs) +* :doc:`/sg_v4` - the legacy predecessor to SG-v6 +* `SG-v6 source code `_ diff --git a/docs/source/support_cores.rst b/docs/source/support_cores.rst new file mode 100644 index 000000000..8e991dd8b --- /dev/null +++ b/docs/source/support_cores.rst @@ -0,0 +1,452 @@ +======================================================== +Support & Utility Cores - QICK Firmware +======================================================== + +.. contents:: + :local: + :depth: 2 + +The three cores on this page -- **axis_constant_iq**, **axis_set_reg**, and +**axis_streamer** -- are small, single-purpose utility blocks that live under +``firmware/ip/`` alongside the readout and signal-generator families but +don't belong to either one. Each is 1-7 RTL files, so rather than a +full page per core (as :doc:`/readout_v2`, :doc:`/sg_v6`, etc. get), they +share this one page, one section each. + +.. _support-constant-iq: + +------------------------------------------------------------------------ +1. axis_constant_iq +------------------------------------------------------------------------ + +1.1 General Description +^^^^^^^^^^^^^^^^^^^^^^^^ + +**axis_constant_iq** (``firmware/ip/axis_constant_iq/``, top module +``axis_constant_iq.sv``) is the simplest signal source in QICK: it holds one +constant, software-written complex (I, Q) value and streams it out on +``m_axis`` forever, once armed. As the Python driver's docstring puts it, it +"plays a constant IQ value, which gets mixed with the DAC's built-in +oscillator" -- the block itself has **no DDS and no envelope memory**. All of +the RF frequency content comes from the RFDC's own digital upconverter +(configured through :meth:`.AbsSignalGen.set_mixer_freq`, inherited by this +driver); ``axis_constant_iq`` only supplies the static baseband amplitude/ +phase that gets mixed up to that frequency. + +This is a deliberate contrast with the two arbitrary/multiplexed generator +families already documented: + +* :doc:`/sg_v6` synthesizes a shaped, arbitrary envelope from a DDS + BRAM + waveform engine, sequenced pulse-by-pulse by tProc-issued descriptors. +* :doc:`/sg_mux8` has no envelope memory either, but does have its own + per-tone DDS (up to 8 simultaneous tones), and is still sequenced by the + tProcessor (a streamed mask + duration selects which tones play, when). + +``axis_constant_iq`` has neither an internal DDS nor a connection to the +tProcessor's timed-pulse mechanism at all -- there is no ``s_axis`` pulse +input on this block's port list. It is a pure "set and forget" AXI-Lite +block: software writes an I/Q value once (or occasionally), and the DAC +continuously outputs it until the next write. + +Internally, ``axis_constant_iq.sv`` instantiates two small support blocks +also under ``src/``: + +* ``axil_slv.sv`` -- a generic, reusable AXI4-Lite register-file slave + (parametrized address/data width and register count). The same block is + reused, independently instantiated, by :ref:`axis_streamer ` + below. +* ``sync_nxm.sv`` -- a small parametrized (N-stage, M-bit) synchronizer, + used here to cross the single-bit ``WE_REG`` "commit" strobe from the + AXI-Lite clock domain (``s_axi_aclk``) into the sample-stream clock domain + (``m_axis_aclk``). + +Two other files in ``src/`` (``axi4_lite_if.sv``, ``axi4_stream_if.sv``) are +SystemVerilog verification interfaces (their headers describe them as +testbench-oriented, SVUnit-style protocol tasks) -- they are not instantiated +anywhere in ``axis_constant_iq.sv``'s actual datapath. + +**Update sequencing.** Software writes the new I and Q values to +``REAL_REG``/``IMAG_REG``, then pulses ``WE_REG`` (write 1, then write 0). +On the ``m_axis_aclk`` side, the synchronized ``we`` signal is edge-detected +(``we_int = ~we_r & we``); on that one-cycle pulse, ``real_r``/``imag_r`` are +loaded from the register values and ``m_axis_tvalid`` latches high for good. +From then on ``m_axis_tdata`` continuously presents ``{imag_r, real_r}``, +identically replicated across all ``NUM_CHANNELS`` parallel output lanes, and +``m_axis_tlast`` is tied to 0 -- this is a genuinely unframed, continuous +stream, never packetized. + +1.2 Parameters and Register Map +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: Synthesis parameters + :header-rows: 1 + :widths: 20 15 55 + + * - Parameter + - Default + - Description + * - ``IQ_WIDTH`` + - 16 + - Bit width of each of the I and Q components. + * - ``NUM_CHANNELS`` + - 4 + - Number of identical, parallel ``{Q,I}`` output lanes packed into + ``m_axis_tdata`` (``2*IQ_WIDTH*NUM_CHANNELS`` bits wide total). All + lanes always carry the same value -- there is no per-lane + configuration. + +Registers are exposed through the generic ``axil_slv`` block with +``AXI_DW=32``, ``AXI_AW=6``, ``NUM_REGS=4`` -- 4 word-aligned, 32-bit +registers at byte offsets ``0x00``-``0x0C``: + +.. list-table:: Register map (word index, byte offset) + :header-rows: 1 + :widths: 18 12 12 15 43 + + * - Register + - Index + - Offset + - Width + - Description + * - ``REAL_REG`` + - 0 + - 0x00 + - ``IQ_WIDTH`` bits (signed), low bits of the 32-bit word + - I component, latched into ``real_r`` on the next ``WE_REG`` strobe. + * - ``IMAG_REG`` + - 1 + - 0x04 + - ``IQ_WIDTH`` bits (signed), low bits of the 32-bit word + - Q component, latched into ``imag_r`` on the next ``WE_REG`` strobe. + * - ``WE_REG`` + - 2 + - 0x08 + - bit ``[0]`` + - Write-enable/commit strobe. Edge-detected in the ``m_axis_aclk`` + domain, so software must write 1 then 0 to commit a new I/Q value. + * - (reserved) + - 3 + - 0x0C + - -- + - Tied to 0 in the RTL (``slv_regs_i[3] = '0``); unused. + +1.3 Python Interface +^^^^^^^^^^^^^^^^^^^^^ + +``axis_constant_iq`` is exposed through +``qick.drivers.generator.AxisConstantIQ``, a subclass of +:class:`.AbsSignalGen` (``bindto = ['user.org:user:axis_constant_iq:1.0', +'QICK:QICK:axis_constant_iq:1.0']``, ``HAS_MIXER = True``). Its +``REGISTERS`` dict maps directly onto the word indices above (``real_reg: +0, imag_reg: 1, we_reg: 2``). + +.. code-block:: python + + from qick import * + + soc = QickSoc() + gen = soc.ci_gens[0] # AxisConstantIQ instance for this channel + + gen.set_nyquist(2) # inherited from AbsSignalGen + gen.set_mixer_freq(500.0) # MHz -- picks the actual output frequency + gen.set_iq(i=1.0, q=0.0) # normalized signed gain, -1..1 + +``set_iq(i, q)`` scales the normalized ``(i, q)`` gains (range -1 to 1) by +``MAXV = 2**15-2`` into ``np.int16`` values, writes them to +``real_reg``/``imag_reg``, and calls ``update()``, which performs exactly the +1-then-0 write to ``we_reg`` that the RTL's edge detector expects. On +firmware init (``_init_firmware()``), the driver defaults both registers to +``MAXV`` (full-scale) and commits that value immediately. + +Because this generator is never sequenced by the tProcessor, the +:meth:`.AbsSignalGen.set_nyquist` and :meth:`.AbsSignalGen.set_mixer_freq` +methods it inherits must be called directly by the user -- their docstrings +note this explicitly ("You should normally only call this method directly +for a constant-IQ output"), since for tProc-controlled generators these are +normally invoked automatically as part of program configuration. + +------------------------------------------------------------------------ +2. axis_set_reg +------------------------------------------------------------------------ + +2.1 General Description +^^^^^^^^^^^^^^^^^^^^^^^^ + +**axis_set_reg** (``firmware/ip/axis_set_reg/src/axis_set_reg.sv``) is a +single-file, single-clock-domain "capture and hold" register. Its own header +comment describes it plainly: *"Simple register that captures AXI-Stream +slave data when tvalid is high."* There is no AXI-Lite interface and no +master AXI-Stream output -- just an AXI-Stream slave input (``s_axis_*``) +and a plain ``dout`` output port, ``DATA_WIDTH`` bits wide (default 16, per +``component.xml``). + +The RTL logic is exactly as small as it sounds: + +* On every rising edge of ``s_axis_aclk``, if ``s_axis_tvalid`` is high, + ``dout_r <= s_axis_tdata``; otherwise ``dout_r`` retains its previous + value. +* ``s_axis_tready`` is tied permanently to 1 -- the block never + back-pressures its master. +* ``dout`` is just ``dout_r``, combinationally. +* ``s_axis_tstrb``/``s_axis_tlast`` are present on the port list "for + completeness" (per the header comment) but are not used anywhere in the + RTL body. + +In effect, this block turns a **transient** AXI-Stream beat (valid for one +clock, whenever its master chooses to push one) into a **stable, level-held** +output that persists until the next beat overwrites it. + +2.2 Role in the tProc v1 output chain +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +There is **no dedicated Python driver class** for ``axis_set_reg`` -- a +search of every driver module under ``qick_lib/qick/drivers/`` turns up no +``SocIP`` subclass with a ``bindto`` matching it. The block is referenced +only by its type-name string, ``"axis_set_reg"``, purely at the +hardware-metadata / connectivity-tracing level, in two places: + +* ``qick_lib/qick/ip.py``, ``HardwareMetadata.trace_trigger()`` (around line + 491-514): when this method resolves which tProc port/bit ultimately + triggers a given buffer, and the block driving that trigger is a + ``vect2bits``/``qick_vec2bit`` bit-splitter, it follows that splitter's + ``din`` input back one more hop. If *that* upstream block's type is + ``axis_set_reg``, it follows one further hop through the ``axis_set_reg``'s + own ``s_axis`` input to reach the real originating tProc output port. The + code's own comment spells out the three topologies it has to distinguish, + one of which is exactly:: + + # tproc v1 output port -> axis_set_reg -> vect2bits -> buffer + # tproc v2 data port -> vect2bits -> buffer + # tproc v3 trigger port -> buffer + +* ``qick_lib/qick/drivers/tproc.py``, + ``AxisTProc64x32_x8.configure_connections()`` (around line 130-148): while + enumerating tProc v1's 8 output ports (``m1_axis``..``m8_axis``; port 0 is + reserved for the DMA), for each output found connected to an + ``axis_set_reg``, the code traces that ``axis_set_reg``'s ``dout`` signal + onward and inspects its individual bit taps (``dout0``..``dout15``) to see + whether any of them fan out directly to a top-level FPGA pin. Any pin found + this way is recorded in ``cfg['output_pins']``. + +Combining what the RTL actually does with what these two call sites are +looking for (as far as is verifiable from source, without an actual built +design's HWH file to inspect): ``axis_set_reg`` sits between a tProc v1 +output port and a downstream ``vect2bits`` bit-splitter (or, in some +designs, drives FPGA output pins directly). A tProc v1 output-port write is +a single-beat AXI-Stream transaction -- transient by nature. ``axis_set_reg`` +captures that value and holds it as a stable level on ``dout``, which +``vect2bits`` then decomposes into individual, level-held bits -- used, for +example, to hold a buffer's trigger input high, or to drive a digital output +pin, in between tProc writes. The three-way comment in ``ip.py`` also makes +clear this ``axis_set_reg`` step is specific to tProc v1: tProc v2 drives +``vect2bits`` directly from a data port (no intervening register), and +tProc v3 has dedicated trigger ports that go straight to a buffer. + +**There is no Python API for this block**, and none is needed for its role: +the metadata layer (``qick.ip``/``qick.drivers.tproc``) discovers the +connectivity automatically, by block type name, when the overlay is loaded -- +not through a per-block PYNQ register driver. A QICK user does not interact +with ``axis_set_reg`` directly; they program tProc v1 output-port writes, and +the hardware-metadata tracer figures out which trigger or pin those writes +end up driving. + +.. _support-streamer: + +------------------------------------------------------------------------ +3. axis_streamer +------------------------------------------------------------------------ + +3.1 General Description +^^^^^^^^^^^^^^^^^^^^^^^^ + +**axis_streamer** (``firmware/ip/axis_streamer/``) is, per its own header +comment, *"AXI4-Stream buffer with an AXI4-Lite control interface, for DMA +readout of a captured stream."* The top module (``axis_streamer.sv``) wraps +two pieces: + +* ``axil_slv.sv`` -- the same generic AXI4-Lite register-file block used by + :ref:`axis_constant_iq ` above (independently + instantiated here, not shared logic). +* ``streamer.sv`` -- the actual datapath core. + +``streamer.sv`` captures an input AXI-Stream (``s_axis``, the "s" clock +domain) into a dual-clock asynchronous FIFO (``fifo_async.sv``, built on a +Xilinx ``xpm_fifo_async`` primitive), and re-emits it on a separate output +AXI-Stream (``m_axis``, the "m" clock domain) in fixed-size packets of +``nsamp_reg`` beats, each terminated by ``tlast``. Its header comment states +the intended use case explicitly: a free-running, un-stallable source (e.g. +an ADC feeding this block) on the input side, and a DMA draining the output +side. + +**Clock-domain crossing.** The FIFO itself (an XPM async FIFO) carries the +actual sample data across domains. Every control/status signal that also +needs to cross is individually resynchronized through +``cdc_bit_sync.sv`` (a parametrized N-stage bit synchronizer, 2 stages by +default): ``start_reg`` into the m domain, ``flush_reg`` into the m domain, +the run-state handshake in both directions, and each of the 6 ``STATUS`` +bits individually into the AXI-Lite domain. The RTL comments are explicit +that these are deliberately **not coherent as a group** -- each bit/signal +is only individually meaningful, which is why the register interface exposes +decoded status flags rather than a raw FSM state. + +**Control FSM** (``streamer.sv``): ``IDLE_ST -> RUN_ST -> WAIT_END_ST -> +END_ST``, gated by ``start_reg`` (a level, not a pulse -- dropping it while +running ends the run) and ``mode_reg`` (0 = one-shot: stop after one packet; +1 = continuous: back-to-back packets). ``flush_reg`` controls what happens to +a partial packet when the run ends: 1 drains it (final beat carries +``tlast``), 0 discards it (though a beat already presented on the bus is +still allowed to complete its handshake -- the RTL comments call this out as +a deliberate deviation from an earlier implementation, to stay AXI-legal). + +**Backpressure.** ``s_axis_tready = ~fifo_full``, deliberately *not* gated by +run state -- the header comment describes the block as "a passive tap" that +must never stall its producer. Beats offered while the block is idle are +silently dropped and are **not** counted toward ``lost_reg`` (only beats +dropped while actually running are). + +**What ``LOST``/``OVERFLOW`` actually count.** ``lost_reg`` counts *cycles* +in the s-domain during a run where the source offered a beat while the FIFO +was full -- not distinct beats. The RTL comments are careful to note this +only equals "samples dropped" for a source that cannot be stalled (like a +free-running ADC feeding a DMA); for a well-behaved AXI-Stream master that +holds ``tvalid`` across a stall, the same beat is counted repeatedly and +nothing is actually lost -- in that configuration the counter measures +backpressure, not loss. + +3.2 Register Map +^^^^^^^^^^^^^^^^^ + +Registers are exposed through ``axil_slv`` with ``AXI_DW=32``, ``AXI_AW=6``, +``NUM_REGS=6``. The map below is taken directly from ``axis_streamer.sv``'s +own header comment, which documents it explicitly: + +.. list-table:: Register map (byte-addressed, 32-bit registers) + :header-rows: 1 + :widths: 15 12 10 15 48 + + * - Register + - Offset + - R/W + - Width + - Description + * - ``START`` + - 0x00 + - RW + - bit ``[0]`` + - Block enable. LEVEL, not a pulse. + * - ``FLUSH`` + - 0x04 + - RW + - bit ``[0]`` + - 1 = drain a partial packet with ``tlast`` on stop; 0 = discard it. + * - ``MODE`` + - 0x08 + - RW + - bit ``[0]`` + - 0 = one-shot; 1 = continuous. + * - ``NSAMP`` + - 0x0C + - RW + - ``[31:0]`` + - Beats per packet. 0 keeps the block idle. + * - ``LOST`` + - 0x10 + - RO + - ``[31:0]`` + - Beats dropped while running, latched when the block stops. + * - ``STATUS`` + - 0x14 + - RO + - ``[5:0]`` + - See status bits below. + +.. list-table:: STATUS bits + :header-rows: 1 + :widths: 10 20 70 + + * - Bit + - Name + - Meaning + * - 0 + - ``RUNNING`` + - The core is capturing and streaming. + * - 1 + - ``DONE`` + - One-shot packet finished; clear ``START`` to return to idle. + * - 2 + - ``IDLE`` + - Safe to reconfigure; ``LOST`` holds the last run's count. + * - 3 + - ``OVERFLOW`` + - Sticky: samples were lost during this or the last run. Cleared + automatically when a new run starts. + * - 4 + - ``FIFO_FULL`` + - Instantaneous, diagnostic only. + * - 5 + - ``FIFO_EMPTY`` + - Instantaneous, diagnostic only. + +The header comment also documents the intended software sequence: write +``NSAMP``/``MODE``/``FLUSH`` only while ``STATUS.IDLE`` is set; write +``START=1``; wait for ``tlast`` (one-shot) or run until you choose to stop +(continuous); write ``START=0``; then **poll** ``STATUS.IDLE`` before +reading ``LOST`` -- stopping is not instantaneous, since ``START`` crosses +several flops, so the core keeps streaming for a few cycles after the write +retires. + +3.3 Python Interface -- is ``DataStreamer`` the driver? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +**No.** This is worth stating explicitly, because the name similarity is +misleading and the relationship is not 1:1. + +Verified by searching every driver module under ``qick_lib/qick/drivers/`` +(``generator.py``, ``readout.py``, ``tproc.py``, ``peripherals.py``, +``xcom.py``): none of them defines a ``SocIP``/``DummyIP`` subclass with a +``bindto`` referencing ``axis_streamer``. The only Python artifact anywhere +under ``qick_lib`` that carries the ``axis_streamer`` name is +``qick_lib/qick/rdl_pkgs/axis_streamer_regmap_pkg/`` -- an auto-generated +PeakRDL register-model wrapper (``reg_model/``, ``sim/``, ``tests/``), +generated from an RDL register-map source elsewhere in the repo. That is a +register-level Python model intended for RTL simulation/testbench use (it +ships with its own ``SimTestCase``/``TestCase`` classes), not a PYNQ overlay +driver wired into ``QickSoc``. A repo-wide search also found no reference to +``axis_streamer`` in ``qick_lib/qick/soc.py`` or in any board block-design +file -- so, as far as this repository shows, the core doesn't currently +appear wired into a shipped QICK board bitstream either. + +``qick.streamer.DataStreamer`` (``qick_lib/qick/streamer.py``) is a +completely different, higher-level, **purely software** abstraction: a +background Python ``Thread`` that repeatedly calls ``soc.get_tproc_counter()`` +and ``soc.get_accumulated()`` to pull already-accumulated I/Q points out of +the averaging buffer (:doc:`/avg_buffer`) while a tProc program runs, +queuing the results for the main thread to consume via ``poll_data()``. It +never touches an MMIO register map and never references any of +``axis_streamer``'s ``START``/``FLUSH``/``MODE``/``NSAMP``/``LOST``/ +``STATUS`` registers -- its "streaming" is a software polling loop layered +on top of :doc:`/avg_buffer` and the tProcessor's shot counter, with no +dependency on the ``axis_streamer`` IP block at all. + +So: as verified in this codebase, ``axis_streamer`` currently has no +register-level Python counterpart beyond the auto-generated simulation +register model, and ``DataStreamer`` is not that counterpart -- it solves an +unrelated, software-side data-collection problem that happens to share the +word "stream." Driving ``axis_streamer`` from Python today would require +writing a new ``SocIP`` subclass, following the pattern used by +:ref:`axis_constant_iq ` above or the readout/generator +drivers. + +Related Documentation +---------------------- + +* :doc:`/sg_v6` -- arbitrary-envelope signal generator; contrast with + ``axis_constant_iq``'s lack of any DDS or envelope memory. +* :doc:`/sg_mux8` -- fixed-tone multiplexed generator; also contrasted with + ``axis_constant_iq`` above. +* :doc:`/avg_buffer` -- the buffer that :class:`.DataStreamer` actually + polls, as opposed to ``axis_streamer``. +* :doc:`/readout_dynamic` -- another block whose Python-side object is + constructed manually rather than through the normal PYNQ overlay-scan + mechanism, for comparison with ``axis_set_reg``'s pure metadata-tracing + role. diff --git a/docs/source/topics/XCOM-commands.rst b/docs/source/topics/XCOM-commands.rst new file mode 100644 index 000000000..3b2318b37 --- /dev/null +++ b/docs/source/topics/XCOM-commands.rst @@ -0,0 +1,550 @@ +.. _xcom-commands: + +XCOM Commands Reference +======================= + +This document provides a complete reference for all XCOM commands. Commands are sent either: + +- **Over the network (NET)**: To other boards (OP code MSB = 0) +- **Locally (LOC)**: To the local XCOM instance (OP code MSB = 1) + +NET Command Message Format +-------------------------- + +NET messages have a header followed by data: + +.. list-table:: NET Message Structure + :header-rows: 1 + :widths: 30 30 40 + + * - Field + - Bits + - Description + * - OP + - HEADER[7:4] + - Operation code (4 bits) + * - ADDR + - HEADER[3:0] + - Destination board address + * - DATA + - Variable + - Payload (8, 16, or 32 bits) + +If ``ADDR = 0``, the command is broadcast to all boards in the network. + +LOC Command Message Format +-------------------------- + +LOC commands are written directly to the ``XCOM_CTRL`` register: + +- ``OP_I`` (``ctrl[5:1]``) contains the command +- ``EN`` (``ctrl[0]``) triggers execution (auto-resets after one cycle) + +NET Commands +------------ + +XCOM_CLEAR_FLAG +~~~~~~~~~~~~~~~ + +.. list-table:: Command Format + :header-rows: 1 + + * - Command + - Code + - OP + - DT1 + - DT2 + * - XCOM_CLEAR_FLAG + - 0 + - 00000 + - ADDR + - — + +**Description**: +This is a NET command. Clear the `qp_flag` pin in the external peripheral interface of the QICK processor. This signal can be used to inform the QICK processor some state in the execution of a program between boards. The DT1 register contains the address of the board where to execute the command. + +If ADDR = 0 that means it is a broadcast message and all the boards in the network will execute this command. + +--- + +XCOM_SET_FLAG +~~~~~~~~~~~~~ + +.. list-table:: Command Format + :header-rows: 1 + + * - Command + - Code + - OP + - DT1 + - DT2 + * - XCOM_SET_FLAG + - 1 + - 00001 + - ADDR + - — + +**Description**: + This is a NET command. Set the `qp_flag` pin in the external peripheral interface of the QICK processor. This signal can be used to + inform the QICK processor some state in the execution of a program between boards. + The DT1 register contains the address of the board where to execute the command. + +If ADDR = 0 that means it is a broadcast message and all the boards in the network will execute this command. + +Sets the ``qp_flag`` pin on the specified remote board. + +--- + +XCOM_SEND_8BIT +~~~~~~~~~~~~~~ + +.. list-table:: Command Format + :header-rows: 1 + + * - Command + - Code + - OP + - DT1 + - DT2 + * - XCOM_SEND_8BIT_1 + - 2 + - 00010 + - ADDR + - DATA[7:0] + * - XCOM_SEND_8BIT_2 + - 3 + - 00011 + - ADDR + - DATA[7:0] + +**Description**: +These are NET commands. Sends a byte of data to the board with address ADDR. DT1 +register selects where to write the data in DT2 register. + +* With `XCOM_SEND_8BIT_1` the data contained in DT2 is written into the `qp_dt1` + and into the `o_time_update_data` outputs. This command writes to the registers + in the CORE processor of the receiving (ADDR) board. + +* With `XCOM_SEND_8BIT_2` the data contained in DT2 is written into the 16x32 + memory of the receiving (ADDR) board. + +If ADDR = 0 that means it is a broadcast message and all the boards in the +network will execute this command. + +--- + +XCOM_SEND_16BIT +~~~~~~~~~~~~~~~ + +.. list-table:: Command Format + :header-rows: 1 + + * - Command + - Code + - OP + - DT1 + - DT2 + * - XCOM_SEND_16BIT_1 + - 4 + - 00100 + - ADDR + - DATA[15:0] + * - XCOM_SEND_16BIT_2 + - 5 + - 00101 + - ADDR + - DATA[15:0] + +**Description**: +These are NET commands. Sends 16-bit data to the board with address ADDR. DT1 +register selects where to write the data in DT2 register. + +* With `XCOM_SEND_16BIT_1` the data contained in DT2 is written into the `qp_dt1` + and into the `o_time_update_data` outputs. This command writes to the registers + in the CORE processor of the receiving (ADDR) board. + +* With `XCOM_SEND_16BIT_2` the data contained in DT2 is written into the 16x32 + memory of the receiving (ADDR) board. + +If ADDR = 0 that means it is a broadcast message and all the boards in the +network will execute this command. + +--- + +XCOM_SEND_32BIT +~~~~~~~~~~~~~~~ + +.. list-table:: Command Format + :header-rows: 1 + + * - Command + - Code + - OP + - DT1 + - DT2 + * - XCOM_SEND_32BIT_1 + - 6 + - 00110 + - ADDR + - DATA[31:0] + * - XCOM_SEND_32BIT_2 + - 7 + - 00111 + - ADDR + - DATA[31:0] + +**Description**: +These are NET commands. Sends 32-bit data to the board with address ADDR. DT1 +register selects where to write the data in DT2 register. + +* With `XCOM_SEND_32BIT_1` the data contained in DT2 is written into the `qp_dt1` + and into the `o_time_update_data` outputs. This command writes to the registers + in the CORE processor of the receiving (ADDR) board. + +* With `XCOM_SEND_32BIT_2` the data contained in DT2 is written into the 16x32 + memory of the receiving (ADDR) board. + +If ADDR = 0 that means it is a broadcast message and all the boards in the +network will execute this command. + +--- + +XCOM_QRST_SYNC +~~~~~~~~~~~~~~ + +.. list-table:: Command Format + :header-rows: 1 + + * - Command + - Code + - OP + - DT1 + - DT2 + * - XCOM_QRST_SYNC + - 8 + - 01000 + - ADDR + - — + +**Description**: +This is a NET command. DT1 register selects the address of the board to which +the local board wants to synchronize to. The transmitter board waits for the +next rising edge in the PPS signal (synchronization signal) to send the +command and at the same time it will wait for the next rising edge of the +PPS signal to set the local `o_proc_start` signal. The receiving board, +once receive the `XCOM_QRST_SYNC` command will wait for the next rising +edge in the PPS signal and then will set the `o_proc_start` signal to +let the QICK processor start with its operations. The `o_proc_start` signal +will remain settled for 8 `t_clk` clock cycles and then goes to zero again. +In that way, all the connected boards will start its QICK processor +operations at the same time, that means 2 PPS after the `XCOM_QRST_SYNC` +command was issued by the initial (master/main) board. + +If ADDR = 0 that means it is a broadcast message and all the boards in +the network will execute this command. + +--- + +XCOM_AUTO_ID +~~~~~~~~~~~~ + +.. list-table:: Command Format + :header-rows: 1 + + * - Command + - Code + - OP + - DT1 + - DT2 + * - XCOM_AUTO_ID + - 9 + - 01001 + - — + - — + +**Description**: +This is a NET command. The board receiving this command will auto +assign itself a board ID calculated as the ID of the transmitter +board plus one, so RX ID = TX ID + 1. + +--- + +XCOM_UPDATE_DT8 / 16 / 32 +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: Command Format + :header-rows: 1 + + * - Command + - Code + - OP + - DT1 + - DT2 + * - XCOM_UPDATE_DT8 + - 10 + - 01010 + - ADDR + - DATA + * - XCOM_UPDATE_DT16 + - 12 + - 01100 + - ADDR + - DATA + * - XCOM_UPDATE_DT32 + - 14 + - 01110 + - ADDR + - DATA + +**Description**: +This is a NET command and for now they are just placeholders for future +implementations. Not specific task assigned yet. + +--- + +XCOM_QCTRL +~~~~~~~~~~ + +.. list-table:: Command Format + :header-rows: 1 + + * - Command + - Code + - OP + - DT1 + - DT2 + * - XCOM_QCTRL + - 11 + - 01011 + - ADDR + - CONTROL[31:0] + +**Description**: +This is a NET command. DT1 register selects the board where to write the data +in DT2 register. This command is related to the control of the QICK processor, +see details in :doc:`xcom`. + +It depends on what DT2[2:0] contains to select what to do in the receiving board: + +* DT2[2:0] = 0, N/A. +* DT2[2:0] = 1, N/A. +* DT2[2:0] = 2, the `o_time_rst` signal is set for 8 `t_clk` clock cycles and then goes to zero again. +* DT2[2:0] = 3, the `o_time_update` signal is set for 8 `t_clk` clock cycles and then goes to zero again. +* DT2[2:0] = 4, the `o_core_start` signal is set for 8 `t_clk` clock cycles and then goes to zero again. +* DT2[2:0] = 5, the `o_core_stop` signal is set for 8 `t_clk` clock cycles and then goes to zero again. +* DT2[2:0] = 6, the `o_proc_start` signal is set for 8 `t_clk` clock cycles and then goes to zero again. +* DT2[2:0] = 7, the `o_proc_stop` signal is set for 8 `t_clk` clock cycles and then goes to zero again. + +.. list-table:: Control Encoding + :header-rows: 1 + + * - DT2[2:0] + - Operation + - Description + * - 2 + - Time reset + - Reset time counter + * - 3 + - Time update + - Update time + * - 4 + - Core start + - Start core + * - 5 + - Core stop + - Stop core + * - 6 + - Proc start + - Start processor + * - 7 + - Proc stop + - Stop processor + +--- + +XCOM_RFU +~~~~~~~~ + +.. list-table:: Command Format + :header-rows: 1 + + * - Command + - Code + - OP + - DT1 + - DT2 + * - XCOM_RFU_1 + - 13 + - 01101 + - — + - — + * - XCOM_RFU_2 + - 15 + - 01111 + - — + - — + +**Description**: + This are NET commands and for now they are just placeholders for future + implementations. Not specific task assigned yet. + +--- + +LOC Commands +------------ + +XCOM_SET_ID +~~~~~~~~~~~ + +.. list-table:: Command Format + :header-rows: 1 + + * - Command + - Code + - OP + - DT1 + - DT2 + * - XCOM_SET_ID + - 16 + - 10000 + - ID + - — + +**Description**: +This is a LOC command. Set the ID of the board locally. The DT1 register +contains the desired ID. The ID must be a number between 1 and 15. + +--- + +XCOM_WRITE_FLAG +~~~~~~~~~~~~~~~ + +.. list-table:: Command Format + :header-rows: 1 + + * - Command + - Code + - OP + - DT1 + - DT2 + * - XCOM_WRITE_FLAG + - 17 + - 10001 + - FLAG + - — + +**Description**: +This is a LOC command. Set the `qp_flag` pin in the external peripheral interface +of the QICK processor. This signal can be used to inform the QICK processor some +state in the execution of a program between boards. The DT1[0] bit is used to +set (1) or unset (0) this flag. + +--- + +XCOM_WRITE_REG +~~~~~~~~~~~~~~ + +.. list-table:: Command Format + :header-rows: 1 + + * - Command + - Code + - OP + - DT1 + - DT2 + * - XCOM_WRITE_REG + - 18 + - 10010 + - SEL + - DATA[31:0] + +**Description**: +This is a LOC command. DT1 register selects where to write the data in DT2 +register. If DT1[0] = 0, the data contained in DT2 is written into the `qp_dt1` +output. If DT1[0] = 1 the data contained in DT2 is written into the `qp_dt2` +output. This command writes to the registers in the CORE processor. When DT1[0] += 0 this command also writes the data in DT2 register into the +`o_time_update_data` output. + +--- + +XCOM_WRITE_MEM +~~~~~~~~~~~~~~ + +.. list-table:: Command Format + :header-rows: 1 + + * - Command + - Code + - OP + - DT1 + - DT2 + * - XCOM_WRITE_MEM + - 19 + - 10011 + - ADDR + - DATA[31:0] + +**Description**: +This is a LOC command. DT1 register selects the address where to write the data +in DT2 register. Address range is 0 - 15. This command writes to the internal +16x32 memory. + +--- + +XCOM_RST +~~~~~~~~ + +.. list-table:: Command Format + :header-rows: 1 + + * - Command + - Code + - OP + - DT1 + - DT2 + * - XCOM_RST + - 31 + - 11111 + - — + - — + +**Description**: +This is a LOC command. It reset all the internal registers in the local `xcom` +instance. + +--- + +Python API Example +------------------ + +.. code-block:: python + + from qick.pyro import make_proxy + + # Connect to board + soc = make_proxy("board_ip_address") + + # Reset XCOM + soc.xcom_0.run_cmd(soc.xcom_0.opcodes['XCOM_RST'], 0, 0) + + # Auto-assign IDs + soc.xcom_0.run_cmd(soc.xcom_0.opcodes['XCOM_AUTO_ID'], 0, 0) + + # Set local ID to 2 + soc.xcom_0.set_local_id(2) + + # Send 32-bit data to board 5 + soc.xcom_0.send_word(0xDEADBEEF, dst=5, reg=2) + + # Read status + soc.xcom_0.print_status() + +See Also +-------- + +* :doc:`xcom` — XCOM overview and architecture + +* `XCOM Network Synchronization <../tutorials/14_XCOM_Network_Synchronization.ipynb>`_ — XCOM demonstration notebook + +* `XCOM paper (arXiv:2603.18977v1) `_ diff --git a/docs/source/topics/asmv2_cheatsheet.rst b/docs/source/topics/asmv2_cheatsheet.rst new file mode 100644 index 000000000..8d820705a --- /dev/null +++ b/docs/source/topics/asmv2_cheatsheet.rst @@ -0,0 +1,264 @@ +tProc v2 ASM Cheatsheet +======================= + +This cheatsheet is for the **tProcessor v2** (72-bit instructions, 32-bit registers). +For the complete reference manual, see :doc:`/tprocv2_trm`. + +Quick Reference +--------------- + +.. list-table:: + :header-rows: 1 + :widths: 40 60 + + * - Operation + - Assembly Code + * - Load immediate to register + - ``REG_WR r0 imm #100`` + * - Copy register to register + - ``REG_WR r1 op -op(r0)`` + * - Load from DMEM + - ``REG_WR r0 dmem [&10]`` + * - Store to DMEM + - ``DMEM_WR [&10] imm #42`` + * - Load waveform from WMEM + - ``REG_WR r_wave wmem [&5]`` + * - Store waveform to WMEM + - ``WMEM_WR [&5]`` + * - Write data port + - ``DPORT_WR p0 imm 1 @1000`` + * - Write trigger + - ``TRIG p0 set @150`` + * - Write wave port + - ``WPORT_WR p1 r_wave @1000`` + * - Read input port + - ``DPORT_RD p0`` + * - Conditional jump + - ``JUMP LABEL -if(NZ)`` + * - Call subroutine + - ``CALL MY_SUB`` + * - Return from subroutine + - ``RET`` + * - Wait for time + - ``WAIT time @1000`` + * - Wait for division + - ``WAIT div_dt`` + * - Wait for ARITH (no WAIT macro; poll manually) + - ``TEST -op(s_status AND bit_arith_new) -uf`` / ``JUMP HERE -if(Z)`` + * - Wait for input data + - ``WAIT port_dt`` + * - Start division + - ``DIV r1 r2`` + * - Start multiply (ARITH) + - ``ARITH T r1 r2`` + * - Multiply-accumulate + - ``ARITH PTP r1 r2 r3 r4`` ``; (r1+r2)*r3+r4`` + * - Set internal flag + - ``FLAG set`` + * - Clear internal flag + - ``FLAG clr`` + * - Reset time + - ``TIME rst`` + * - Increment reference time + - ``TIME inc_ref #100`` + * - Clear peripheral flag + - ``CLEAR arith`` + * - No operation + - ``NOP`` + +Condition Codes +--------------- + +.. list-table:: + :header-rows: 1 + :widths: 20 40 40 + + * - Code + - Condition + - Use Case + * - ``-if(Z)`` + - Zero (result == 0) + - Check if counter reached zero + * - ``-if(NZ)`` + - Non-zero (result != 0) + - Loop while counter > 0 + * - ``-if(S)`` + - Negative (result < 0) + - Check threshold crossing + * - ``-if(NS)`` + - Non-negative (result >= 0) + - Opposite of S + * - ``-if(F)`` + - Flag set + - Wait for external trigger + * - ``-if(NF)`` + - Flag clear + - Wait for flag to clear + +Address Modes +------------- + +.. list-table:: + :header-rows: 1 + :widths: 30 30 40 + + * - Mode + - Syntax + - Example + * - Literal (DMEM) + - ``[&addr]`` + - ``DMEM_WR [&10] imm #5`` + * - Register (DMEM) + - ``[rX]`` + - ``DMEM_WR [r0] imm #5`` + * - Indexed literal (DMEM) + - ``[rX + &offset]`` + - ``DMEM_WR [r1+&4] imm #5`` + * - Indexed register (DMEM) + - ``[rX + rY]`` + - ``DMEM_WR [r2+r3] imm #5`` + * - Literal (WMEM) + - ``[&addr]`` + - ``WMEM_WR [&10]`` + * - Register (WMEM) + - ``[rX]`` + - ``WMEM_WR [r0]`` + +Python Examples +--------------- + +**Basic program loading:** + +.. code-block:: python + + import numpy as np + from qick import * + from qick.tprocv2_assembler import Assembler + + soc = QickSoc() + + asm_code = """ + REG_WR r0 imm #100 + DPORT_WR p0 reg r0 @1000 + .END + """ + + # 1. Assembly + _, bin_arr = Assembler.str_asm2bin(asm_code) + # 2. Convert to ndarray int32 (N,8) -- must be int32, the assembler + # packs each 72-bit instruction into three ints (two 32-bit + one 8-bit) + buff = np.array(bin_arr, dtype=np.int32) + # 3. Load in pmem + soc.tproc.load_mem('pmem', buff, check=False) + # 4. Execute + soc.tproc.start() + + +**Waveform loading and playback:** + +.. code-block:: python + + # Load waveform to WMEM using the correct method for tProc V2 + def pack_waveform(freq, phase, env, gain, length, conf): + """Pack waveform parameters into 8-word (256-bit) format for tProc WMEM""" + wave = np.zeros(8, dtype=np.int32) + wave[0] = freq & 0xFFFFFFFF # 32-bit frequency + wave[1] = phase & 0xFFFFFFFF # 32-bit phase + wave[2] = env & 0xFFFFFF # 24-bit envelope index (w_env) + wave[3] = gain & 0xFFFFFFFF # 32-bit gain + wave[4] = length & 0xFFFFFFFF # 32-bit length + wave[5] = conf & 0xFFFF # 16-bit config (w_conf) + return wave.reshape(1, 8) + + # Create and pack waveform + waveform_data = pack_waveform( + freq=100_000_000, # 100 MHz + phase=0, + env=0, + gain=32768, # 1.0 (max) + length=1024, + conf=0 + ) + + # Load waveform to WMEM (tProc V2 method) + soc.tproc.load_mem('wmem', waveform_data, addr=0, check=False) + + # Assembly program to play waveform (corrected syntax) + asm_code = """ + WAIT time @1000 ; Wait for 1000 clock cycles + WPORT_WR p0 wmem [&0] ; Play waveform directly from WMEM address 0 + .END + """ + + # Assemble and run + _, bin_arr = Assembler.str_asm2bin(asm_code) + buff = np.array(bin_arr, dtype=np.int32) + soc.tproc.load_mem('pmem', buff, check=False) + soc.tproc.start() + +**Feedback Example (read ADC, conditional output)** + +.. code-block:: python + + asm_feedback = """ + LOOP: + WAIT port_dt + DPORT_RD p0 + TEST -op(s_port_l - #32768) -uf + JUMP LOAD_HIGH -if(NS) + JUMP LOAD_LOW -if(S) + + LOAD_HIGH: + REG_WR r_wave wmem [&0] + WPORT_WR p0 r_wave @1000 + JUMP NEXT + + LOAD_LOW: + REG_WR r_wave wmem [&1] + WPORT_WR p0 r_wave @1000 + JUMP NEXT + + NEXT: + JUMP LOOP + + .END + """ + +**Optional, adding a counter (iterations)** + +.. code-block:: python + + asm_feedback_with_counter = """ + DMEM_WR [&0] imm #100 + + LOOP: + WAIT port_dt + DPORT_RD p0 + TEST -op(s_port_l - #32768) -uf + JUMP LOAD_HIGH -if(NS) + JUMP LOAD_LOW -if(S) + + LOAD_HIGH: + REG_WR r_wave wmem [&0] + WPORT_WR p0 r_wave @1000 + JUMP DEC + + LOAD_LOW: + REG_WR r_wave wmem [&1] + WPORT_WR p0 r_wave @1000 + JUMP DEC + + DEC: + DMEM_WR [&0] imm #99 + JUMP LOOP + + .END + """ + +Related Documentation +--------------------- + +* :doc:`/tprocv2_trm` - Complete tProcessor v2 reference manual +* :doc:`/firmware` - Firmware overview and channel assignments +* :doc:`/sg_v6` - Signal Generator v6 documentation +* :doc:`/readout` - Readout system documentation diff --git a/docs/topics/changing_fs.rst b/docs/source/topics/changing_fs.rst similarity index 100% rename from docs/topics/changing_fs.rst rename to docs/source/topics/changing_fs.rst diff --git a/docs/source/topics/freq_matching.rst b/docs/source/topics/freq_matching.rst new file mode 100644 index 000000000..6308f2531 --- /dev/null +++ b/docs/source/topics/freq_matching.rst @@ -0,0 +1,79 @@ +How to ensure frequency matching +================================ + +Generators (SG-v6) and readouts have different frequency units because they run on different clocks (DAC clock vs ADC clock, with different sampling rates). +For coherent measurements, the upconversion frequency (DAC) and downconversion frequency (ADC) must be **exactly equal**. +If they are not, the acquired data will show a sliding phase, making it impossible to get consistent results. + +Frequency Matching Methods +-------------------------- + +There are two ways to ensure frequency matching in QICK: + +**Method 1: Match during conversion (recommended)** + +When converting a frequency to an integer register value, specify both the channel you are configuring and the channel you want to frequency-match to: + +.. code-block:: python + + from qick import * + + soc = QickSoc() + soccfg = soc + + # Convert frequency for generator 0, matching to readout 0 (freq2reg takes MHz) + freq_reg = soccfg.freq2reg(100.0, gen_ch=0, ro_ch=0) + + # Or for readout, matching to generator 0 + freq_reg = soccfg.freq2reg_adc(100.0, ro_ch=0, gen_ch=0) + +**Method 2: Pre-round the frequency** + +Round the frequency to the closest value that is valid on both channels: + +.. code-block:: python + + # Get the nearest frequency (in MHz) that works for both gen_ch=0 and ro_ch=0 + matched_freq = soccfg.adcfreq(100.0, gen_ch=0, ro_ch=0) + freq_reg = soccfg.freq2reg(matched_freq, gen_ch=0) + +Trade-offs +---------- + +Frequency matching **reduces frequency resolution**, because the smallest step is now the least common multiple (LCM) of the two channels' frequency steps. + +- Typical resolution: ~10 Hz, which is sufficient for most qubit experiments +- To disable matching (if you need finer resolution), specify `None` as the other channel: + +.. code-block:: python + + # No matching - highest resolution + freq_reg = soccfg.freq2reg(100.0, gen_ch=0, ro_ch=None) + +Multiple Generators +------------------- + +If you have two generators that need to be phase-locked (e.g., for qubit drive and cavity drive), both should be frequency-matched to the same readout: + +.. code-block:: python + + # Match both generators to readout 0 + freq_reg_drive = soccfg.freq2reg(100.0, gen_ch=0, ro_ch=0) + freq_reg_cavity = soccfg.freq2reg(100.0, gen_ch=1, ro_ch=0) + +If they are matched to different readouts (or not matched), they will have slightly different frequencies and the phase between them will drift. + +Best Practices +-------------- + +- In most QICK firmwares, all generators and readouts have the same sampling frequency, so matching to channel 0 works for everything. +- Make it a habit to always specify the matched channel explicitly. +- Use `soccfg.freq2reg()` for generator channels and `soccfg.freq2reg_adc()` for readout channels, always passing the other channel to match against. + +Related Documentation +--------------------- + +* :doc:`/sg_v6` - Signal Generator v6 +* :doc:`/readout` - Readout system +* :doc:`/firmware` - Clock domains and sample rates +* :doc:`changing_fs` - Custom sample rates diff --git a/docs/topics/gen_config.rst b/docs/source/topics/gen_config.rst similarity index 100% rename from docs/topics/gen_config.rst rename to docs/source/topics/gen_config.rst diff --git a/docs/source/topics/index.rst b/docs/source/topics/index.rst new file mode 100644 index 000000000..7b2b89acd --- /dev/null +++ b/docs/source/topics/index.rst @@ -0,0 +1,93 @@ +Technical Topics +================ + +This section contains detailed technical reference material for advanced users. + +These topics assume you have completed the basic tutorials (00-05) and are familiar with: +- QICK program structure (`_initialize`, `_body`) +- Pulse definition and sequencing +- Basic readout configuration + +.. toctree:: + :maxdepth: 1 + :caption: Core Concepts + + freq_matching + timing + playing_pulses + gen_config + readout_modes + units + reference_clock + changing_fs + +.. toctree:: + :maxdepth: 1 + :caption: Quick Reference + + asmv2_cheatsheet + tutorials + +.. toctree:: + :maxdepth: 1 + :caption: Advanced Topics + + xcom + XCOM-commands + pyro4 + +Topic Descriptions +================== + +**freq_matching** + How frequency matching works between generators and readouts in tProc v2 vs. v1. + +**timing** + Detailed explanation of timeline management, delays, and synchronization. + +**playing_pulses** + How to define and play pulses with different styles (const, arb, flat_top). + +**gen_config** + Complete reference for generator configuration parameters. + +**readout_modes** + Accumulated (``acquire``) vs. decimated (``acquire_decimated``) readout: what + each mode returns, when to use which, and their shared setup. + +**units** + Understanding QICK's time, frequency, and amplitude units. + +**reference_clock** + Configuring external reference clocks and clock distribution. + +**changing_fs** + How to change the FPGA sampling frequency for different bandwidths. + +**asmv2_cheatsheet** + Quick reference for tProc v2 assembly instructions. + +**tutorials** + Link to the full Jupyter notebook tutorials. + +**xcom** + XCOM: Full mesh network for multi-board synchronization and low-latency communication. Covers hardware requirements, communication protocol, command set, and Python interface. + +**XCOM-commands** + Complete reference of all XCOM commands, including NET commands (for network communication) and LOC commands (for local control). + +**pyro4** + Pyro4: Network-based multi-board connection for distributed control and data acquisition. + +When to Use Each Topic +====================== + +- **New to timing concepts?** Start with :doc:`timing` +- **Confused about frequencies?** Read :doc:`freq_matching` +- **Need to shape pulses?** See :doc:`playing_pulses` +- **Changing hardware config?** Check :doc:`gen_config` and :doc:`changing_fs` +- **Not sure whether to use `acquire` or `acquire_decimated`?** See :doc:`readout_modes` +- **Using external clock?** Refer to :doc:`reference_clock` +- **Writing assembly code?** Keep :doc:`asmv2_cheatsheet` handy +- **Synchronizing multiple boards?** Read :doc:`xcom` for the network-based solution +- **Need XCOM command details?** See :doc:`XCOM-commands` for the complete command reference \ No newline at end of file diff --git a/docs/source/topics/playing_pulses.rst b/docs/source/topics/playing_pulses.rst new file mode 100644 index 000000000..d39d4e5a0 --- /dev/null +++ b/docs/source/topics/playing_pulses.rst @@ -0,0 +1,148 @@ +How to play pulses with QICK +============================ + +.. note:: + Earlier revisions of this page built every example around raw + ``WPORT_WR`` assembly, a fictional ``tproc.load_wave()``/ + ``gen.load_waveform()``/``gen.set_pulse()`` API, and claimed + :meth:`.QickProgram.pulse` "is designed for the older tProc v1 API" -- + the opposite is true: :meth:`.QickProgram.pulse` (specifically + :meth:`.QickProgramV2.pulse`) *is* the current, recommended way to play a + pulse on tProc v2, and every other page in this doc set uses it. This + page was rewritten to match, verified against ``qick.qick_asm``/ + ``qick.asm_v2`` in the same session that found the problem. + +With the tProcessor v2 and Signal Generator v6 (or any of QICK's other +generator cores -- see :doc:`/generators`), playing a pulse involves three +steps, all done through a :class:`.QickProgram` subclass: + +.. contents:: + :local: + :depth: 2 + +Overview +-------- + +1. **Declare the generator** (once, in ``_initialize()``) -- see + :meth:`.QickProgram.declare_gen`. +2. **Load an envelope** (optional -- skip for rectangular "const" pulses) + and **define the pulse**, giving it a name -- see + :meth:`.QickProgram.add_envelope` and :meth:`.QickProgram.add_pulse`. +3. **Play it by name at a chosen time** -- see :meth:`.QickProgram.pulse`. + +Step 1: Loading a waveform envelope +------------------------------------ + +(You skip this step for rectangular "const" pulses, which have no envelope.) + +Each generator with envelope memory (SG-v6, SG-v4, SG-int4-v2 -- not the +multiplexed SG-Mux8/SG-MixMux8 cores, which play fixed tones instead; see +:doc:`/generators`) stores I/Q envelope data internally. Multiple envelopes +can be stored per generator, and one envelope can be reused across several +pulses (e.g. a Gaussian shape reused for pulses at different frequencies). + +Upload envelope samples with :meth:`.QickProgram.add_envelope`, or use one +of the built-in shape generators that call it for you: + +.. code-block:: python + + from qick import * + + class MyProgram(AveragerProgramV2): + def _initialize(self, cfg): + self.declare_gen(ch=0, nqz=1) + + # Option A: build the envelope yourself and register it + import numpy as np + n_samples = 1024 + sigma = n_samples / 6 + idata = 30000 * np.exp(-0.5 * ((np.arange(n_samples) - n_samples/2) / sigma)**2) + self.add_envelope(ch=0, name="my_gauss", idata=idata.astype(np.int16)) + + # Option B: use a built-in shape helper (equivalent to the above) + self.add_gauss(ch=0, name="my_gauss2", sigma=0.05, length=0.3) + +**Built-in envelope shape helpers** (all call ``add_envelope`` internally): + +- :meth:`.AbsQickProgram.add_gauss` - Gaussian pulse +- :meth:`.AbsQickProgram.add_triangle` - Triangular pulse +- :meth:`.AbsQickProgram.add_cosine` - Raised-cosine pulse +- :meth:`.AbsQickProgram.add_DRAG` - DRAG pulse for qubit control +- :meth:`.AbsQickProgram.add_envelope` - Custom arbitrary waveform (used above) + +Step 2: Defining the pulse +--------------------------- + +Pulse parameters (frequency, phase, gain, length, envelope, output style) +are set with :meth:`.QickProgram.add_pulse`, which registers a named pulse +you'll play later. The available parameters depend on ``style``: + +.. code-block:: python + + # A rectangular pulse -- no envelope needed + self.add_pulse(ch=0, name="square", style="const", + freq=100.0, phase=0, gain=0.5, length=1.0) # MHz, deg, -1..1, us + + # A shaped pulse, using an envelope registered in Step 1 + self.add_pulse(ch=0, name="shaped", style="arb", + freq=100.0, phase=0, gain=0.9, envelope="my_gauss") + + # A flat-top pulse: an envelope for the rise/fall, flat in between + self.add_pulse(ch=0, name="flattop", style="flat_top", + freq=100.0, phase=0, gain=0.7, length=0.5, envelope="my_gauss") + +**Dynamic parameter sweeps** (e.g. frequency) don't need a hand-written +loop that rewrites registers each iteration -- pass a :func:`.QickSweep1D` +as the parameter value and use :meth:`.QickProgram.add_loop`: + +.. code-block:: python + + self.add_loop("freq_loop", 100) + self.add_pulse(ch=0, name="chirp", style="const", + freq=QickSweep1D("freq_loop", 50.0, 150.0), + phase=0, gain=0.5, length=0.1) + +See :doc:`/tprocv2_trm`'s Chapter 13 for a complete sweep example, and +:doc:`/tprocv2_trm` for what ``add_pulse``/``pulse`` compile down to under +the hood (the 168-bit ``r_wave`` bus and ``WPORT_WR`` instruction), if you +need that level of detail. + +Step 3: Firing the pulse +------------------------- + +:meth:`.QickProgram.pulse` schedules a named pulse (defined in Step 2) to +play at a given time, relative to the current shot: + +.. code-block:: python + + def _body(self, cfg): + self.pulse(ch=0, name="square", t=0) + +**Triggering a readout at the same time as a pulse** -- pass both to the +same or a separate :meth:`.QickProgramV2.trigger` call at the matching time +(see :doc:`/readout`'s Python Interface section for the full +``declare_readout``/``trigger``/``acquire`` workflow): + +.. code-block:: python + + def _body(self, cfg): + self.trigger(ros=[0], t=0) + self.pulse(ch=0, name="square", t=0) + +**Running the program** (this is what actually drives +``tproc.time_reset()``/``tproc.start()`` for you): + +.. code-block:: python + + prog = MyProgram(soccfg, reps=1000, final_delay=10.0, cfg={}) + iq = prog.acquire(soc) + +Related Documentation +--------------------- + +* :doc:`/tprocv2_trm` - tProcessor v2 instruction set and register-level detail +* :doc:`/generators` - Which generator cores support envelopes vs. fixed tones +* :doc:`/sg_v6` - Signal Generator v6 documentation, with more worked examples +* :doc:`/readout` - Declaring and triggering a readout alongside a pulse +* :doc:`/firmware` - Channel assignments and firmware overview +* :doc:`tutorials` - tProc v2 tutorial examples diff --git a/docs/source/topics/pyro4.rst b/docs/source/topics/pyro4.rst new file mode 100644 index 000000000..287723a66 --- /dev/null +++ b/docs/source/topics/pyro4.rst @@ -0,0 +1,173 @@ +.. _pyro4: + +Pyro4: Multi-Board Connection and Distributed Control +====================================================== + +Pyro4 (Python Remote Objects) enables communication between multiple QICK boards over a network. This is essential for: + +- Running synchronized experiments across multiple RFSoC boards +- Distributing control and readout tasks +- Building scalable quantum control systems + +.. note:: + Pyro4 is different from XCOM. Pyro4 operates at the software/network level (Ethernet), while XCOM is a hardware-level low-latency solution using LVDS signals. Use Pyro4 for flexibility and ease of use; use XCOM for sub-100 ps synchronization and deterministic latency below 200 ns. + +Architecture +------------ + +The Pyro4 setup consists of three components: + +1. **Name Server**: A central registry that keeps track of all available QICK boards +2. **Server**: Runs on each QICK board, exposing its functionality via Pyro +3. **Client**: Your control PC or Jupyter notebook that connects to the name server and calls methods on remote boards + +:: + + ┌─────────────────────────────────────────────────────────────────────────────┐ + │ Pyro4 Architecture │ + ├─────────────────────────────────────────────────────────────────────────────┤ + │ │ + │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ + │ │ QICK #1 │ │ QICK #2 │ │ Client │ │ + │ │ (Server) │ │ (Server) │ │ (Python) │ │ + │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ + │ │ │ │ │ + │ └───────────────────┼───────────────────┘ │ + │ │ │ + │ ┌──────▼──────┐ │ + │ │ Name Server │ │ + │ │ (Pyro NS) │ │ + │ └─────────────┘ │ + │ │ + └─────────────────────────────────────────────────────────────────────────────┘ + +Setup Instructions +------------------ + +Install Pyro4 on all boards and the client machine: + +.. code-block:: bash + + pip install Pyro4 + +Start the name server on a machine accessible by all boards (e.g., your control PC): + +.. code-block:: bash + + python -m Pyro4.naming -n 0.0.0.0 -p 8888 + +Alternatively, use the script from the QICK repository: + +.. code-block:: bash + + wget https://raw.githubusercontent.com/openquantumhardware/qick/main/pyro4/nameserver.sh + chmod +x nameserver.sh + ./nameserver.sh + +On each QICK board, start the Pyro server: + +.. code-block:: python + + from qick.pyro import start_server + + start_server( + ns_host="your_nameserver_host", # IP of the machine running the name server + ns_port=8888, + proxy_name="qick1", # Unique name for this board + external_clk=True, # Optional: use external reference clock + adc_sample_rates={0:3072.0} # Optional: set ADC sample rates + ) + +For production deployments, use the systemd service files from the QICK repository: + +.. code-block:: bash + + wget https://raw.githubusercontent.com/openquantumhardware/qick/main/pyro4/qick_pyro.service + wget https://raw.githubusercontent.com/openquantumhardware/qick/main/pyro4/pyro_service.py + + sudo cp qick_pyro.service /etc/systemd/system/ + sudo systemctl daemon-reload + sudo systemctl enable qick_pyro + sudo systemctl start qick_pyro + +Client Usage +------------ + +In your Jupyter notebook or Python script, connect to the name server and create proxies to each board: + +.. code-block:: python + + from qick.pyro import make_proxy + + # Connect to boards + proxies = [] + for name in ['qick1', 'qick2', 'qick3']: + proxies.append(make_proxy(ns_host="your_nameserver_host", ns_port=8888, proxy_name=name)) + + # Each proxy behaves like a local QickSoc object + for soc, soccfg in proxies: + print(soccfg) + soc.reset_gens() + +Example: Multi-Board Synchronized Acquisition +--------------------------------------------- + +For a complete example, refer to the Jupyter notebooks in the `pyro4` directory of the QICK repository: +`02_client.ipynb `_. + +.. code-block:: python + + import asyncio + from qick.pyro import make_proxy + from qick.asm_v2 import AveragerProgramV2 + + # Connect to boards + proxies = [make_proxy(ns_host="localhost", ns_port=8888, proxy_name=f"qick{i}") for i in range(1, 3)] + + # Define a simple program + class SyncProgram(AveragerProgramV2): + def _initialize(self, cfg): + self.declare_gen(ch=cfg['gen_ch'], nqz=1) + self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len']) + self.add_pulse(ch=cfg['gen_ch'], name="pulse", + style="const", freq=cfg['freq'], + length=cfg['pulse_len'], gain=cfg['gain']) + + def _body(self, cfg): + self.pulse(ch=cfg['gen_ch'], name="pulse", t=0) + self.trigger(ros=[cfg['ro_ch']], t=cfg['trig_time']) + + # Run on each board + results = [] + for soc, soccfg in proxies: + prog = SyncProgram(soccfg, cfg=config) + results.append(prog.acquire(soc)) + + # Process results + for i, iq in enumerate(results): + print(f"Board {i+1} data shape: {iq.shape}") + +Asynchronous Multi-Board Execution +---------------------------------- + +For synchronous execution across multiple boards, use the `run_multi_decimated` helper function (see the :doc:`/tutorials/10_Multi_Board_Synchronization` notebook for details). + +Files Reference +--------------- + +All Pyro4 files are available in the QICK repository: + +- `00_nameserver.ipynb `_ - Tutorial for starting and verifying the name server +- `01_server.ipynb `_ - Tutorial for starting Pyro servers on QICK boards +- `02_client.ipynb `_ - Tutorial for connecting clients to multiple boards +- `nameserver.sh `_ - Shell script to start the name server +- `pyro_service.py `_ - Python module for Pyro service management +- `qick_pyro.service `_ - systemd service file for auto-starting Pyro on boot + +See Also +-------- + +- :doc:`xcom` - Hardware-level low-latency multi-board synchronization +- :doc:`/tutorials/10_Multi_Board_Synchronization` - Software synchronization with external clock and start signals +- `Pyro4 Documentation `_ +- `QICK pyro4 directory on GitHub `_ diff --git a/docs/source/topics/readout_modes.rst b/docs/source/topics/readout_modes.rst new file mode 100644 index 000000000..c3792bcf0 --- /dev/null +++ b/docs/source/topics/readout_modes.rst @@ -0,0 +1,96 @@ +Accumulated vs. decimated readout +================================== + +Every QICK program that reads data back uses one of two acquisition modes, exposed +by :class:`.AcquireMixin` (mixed into :class:`.AveragerProgramV2` and the older +tProc v1 averager classes) as two mutually exclusive methods: + +* :meth:`.AcquireMixin.acquire` -- **accumulated** readout. +* :meth:`.AcquireMixin.acquire_decimated` -- **decimated** readout. + +They read the same hardware trigger and window, but the readout IP integrates the +samples differently before they ever reach software, and the two methods return +data with different shapes for different purposes. You call one or the other, not +both, for a given run of the tProc program (though you can compile a program once +and call `acquire`/`acquire_decimated` on different runs of it, as long as you +haven't changed the number of readout windows). + +Accumulated (``acquire``) +-------------------------- + +The averager readout (``axis_avg_buffer``/``mr_buffer_et``, depending on channel) +integrates every sample in the readout window in hardware, producing a single +complex (I, Q) point per trigger. ``acquire()`` collects one such point per shot, +per declared readout channel, and returns it averaged over reps (and, if +``rounds>1``, over software rounds too): + +* Use this for the vast majority of experiments: anything where you care about + *one number per shot* -- a qubit state population, a resonator response at one + frequency, an S-parameter point. +* Supports software thresholding (``threshold``/``angle``) to convert the + averaged I/Q point into single-shot 0/1 classification before averaging -- + see :meth:`.AcquireMixin.get_shots`. +* Returns much less data than decimated mode, so it comfortably supports large + sweeps (many reps x many expts). +* Raw (pre-averaging, pre-length-normalization) accumulated data is available via + :meth:`.AcquireMixin.get_raw`; per-round data via :meth:`.AcquireMixin.get_rounds`. + +Decimated (``acquire_decimated``) +----------------------------------- + +The decimating readout streams out the *time-domain* I/Q waveform of the readout +window itself (after the readout's own decimation stage, not the raw ADC rate -- +see :doc:`/firmware` for the DDC/decimation chain), instead of a single integrated +point. + +* Use this to look at the readout waveform directly: verifying that your readout + window lines up with the pulse you expect to measure, debugging a bad envelope + or gain setting, or eyeballing a resonator ringdown. +* Returns one waveform per shot per readout trigger -- much larger than + accumulated mode. Buffer memory limits how much you can capture at once (see + the ``buf_maxlen`` check in the method's ``RuntimeError`` if you request too + much); it is not meant for large parameter sweeps. +* No thresholding option -- thresholding operates on the single accumulated + point, which decimated mode doesn't produce. +* Pair with :meth:`.AcquireMixin.get_time_axis` to get a time axis (in us) for + plotting. + +Common setup +------------ + +Both methods require the acquisition to be described first, via +:meth:`.AcquireMixin.setup_acquire` (which needs the tProc counter address and +the loop dimensions -- see :meth:`.AcquireMixin.setup_counter` for the subset of +that needed if you have no readouts at all, e.g. a pure-generator program you +still want a progress bar for). Both accept the same ``rounds``, ``start_src``, +``remove_offset``, and ``step_rounds`` arguments; ``step_rounds=True`` in either +case hands control of the round-by-round loop to your own code via +``prepare_round()``/``finish_round()``/``finish_acquire()``, if you need to +interleave other work between rounds. + +.. list-table:: + :header-rows: 1 + :widths: 25 35 40 + + * - + - ``acquire()`` + - ``acquire_decimated()`` + * - Data per shot + - one (I, Q) point per readout + - one (I, Q) waveform per readout + * - Typical use + - experiments, sweeps + - debugging readout windows/pulses + * - Thresholding + - yes (``threshold``/``angle``) + - no + * - Data volume + - small + - large -- watch buffer limits + +See also +-------- + +* :doc:`/readout` -- the readout hardware itself (DDC, decimation, buffers). +* :doc:`timing` -- how readout windows relate to the tProc's timed queues. +* :doc:`freq_matching` -- keeping generator and readout frequencies in sync. diff --git a/docs/topics/reference_clock.rst b/docs/source/topics/reference_clock.rst similarity index 100% rename from docs/topics/reference_clock.rst rename to docs/source/topics/reference_clock.rst diff --git a/docs/source/topics/timing.rst b/docs/source/topics/timing.rst new file mode 100644 index 000000000..03766d8cb --- /dev/null +++ b/docs/source/topics/timing.rst @@ -0,0 +1,202 @@ +Timing with tProcessor v2 +========================= + +The tProcessor v2 uses a precise timing model based on three time variables. +Understanding these is essential for accurate waveform sequencing. + +.. contents:: + :local: + :depth: 2 + +Overview +-------- + +The tProcessor v2 has a **48-bit absolute time counter** (`t_abs`) that runs at the DAC clock frequency (`t_clk`). This counter is shared by all output channels (wave ports, data ports, triggers). + +Key concepts: +- **Deterministic latency**: ~5 `t_clk` cycles from instruction to output +- **Signed output times**: You can schedule outputs "before" the reference time +- **Non-blocking writes**: Instructions write to FIFOs and continue immediately + +Time Variables +-------------- + +.. list-table:: Time Variables + :header-rows: 1 + :widths: 20 20 60 + + * - Variable + - Width + - Description + * - `t_abs` + - 48 bits + - Absolute time counter. Runs at DAC clock (`t_clk`). Counts from last reset. + * - `t_ref` + - 48 bits + - Reference time offset. Defines where user time = 0. + * - `t_usr` + - 32 bits (read via `s_usr_time`) + - User time = `t_abs - t_ref` (truncated to 32 bits, signed) + * - `t_out_user` + - 32 bits (signed) + - Time specified in port write instructions (`@value` or `@s_out_time`) + * - `t_abs_out` + - 48 bits + - Absolute output time = `t_ref + t_out_user` (calculated by hardware) + +**Why is `t_out_user` signed?** +You can schedule outputs with a **negative** offset. For example, if you set `t_ref` to a future time, negative `t_out_user` allows outputs to occur "before" the new reference. This is useful for synchronizing multiple boards or for pre-calculated sequences. + +Time Instructions +----------------- + +The `TIME` instruction controls the time counters: + +.. code-block:: text + + TIME rst // t_abs = 0, t_ref = 0, core reset + TIME set_ref rX // t_ref = rX (t_abs unchanged) + TIME inc_ref #N // t_ref = t_ref + N + TIME updt #N // t_abs = t_abs + N (rarely used) + +**Typical initialization sequence:** + +.. code-block:: text + + TIME rst // Start from zero + // ... wait for external trigger ... + TIME set_ref r0 // Set t_ref to current t_abs (t_usr becomes 0) + +Scheduling Outputs +------------------ + +**Fixed absolute time (using immediate):** + +.. code-block:: text + + WPORT_WR p1 r_wave @1000 // Output when t_usr reaches 1000 + +**Relative to previous output (using s_out_time):** + +.. code-block:: text + + REG_WR s_out_time imm #1000 + WPORT_WR p1 r_wave @s_out_time + REG_WR s_out_time op -op(s_out_time + #500) + WPORT_WR p1 r_wave @s_out_time // 500 cycles after first + +**Using a register as time source:** + +.. code-block:: text + + REG_WR r0 imm #2000 + WPORT_WR p1 r_wave @r0 // Output when t_usr reaches value in r0 + +Waiting for Time +---------------- + +The `WAIT time @N` macro pauses the tProc until `t_usr >= N`: + +.. code-block:: text + + WAIT time @5000 // Pause execution until t_usr >= 5000 + +**Expansion:** + +.. code-block:: text + + // WAIT time @5000 expands to: + TEST -op(s_usr_time - #5000) + JUMP HERE -if(S) // Loop while s_usr_time < 5000 + +Dispatcher Latency +------------------ + +When you execute a port write instruction (`WPORT_WR`, `DPORT_WR`, `TRIG`), the data is not output immediately. Instead: + +1. **Cycle 1**: CPU writes to FIFO (in `c_clk` domain) +2. **Cycles 2-3**: Clock domain crossing to `t_clk` domain +3. **Cycle 4**: Dispatcher compares `t_abs` with scheduled time +4. **Cycle 5**: Output is updated on the physical pin + +**Total latency:** Approximately **5 `t_clk` cycles** (about 13 ns at 384 MHz). + +.. important:: + This latency is **deterministic** and constant. You can compensate for it by + subtracting 5 cycles from your scheduled times if you need output aligned with + a specific `t_abs` value. + +FIFO Behavior +------------- + +Each output type has its own FIFO: + +- **WFIFO** (Wave): 168-bit data + 48-bit time, depth 8-512 +- **DFIFO** (Data): 32-bit data + 48-bit time, depth 8-512 +- **TFIFO** (Trigger): 1-bit data + 48-bit time, depth 8-512 + +When a FIFO becomes full: +- Default behavior: Core **stalls** until space is available +- With `DISABLE_FIFO_FULL_PAUSE` (tproc_cfg[10]=1): Writes are dropped (data loss) + +**Check FIFO status:** + +.. code-block:: text + + TEST -op(s_status AND #0x4000) // Test FIFO_FULL bit (bit 14) + JUMP FIFO_OK -if(Z) // Continue if not full + +Clock Domains +------------- + +The tProcessor has three clock domains: + +.. list-table:: + :header-rows: 1 + :widths: 20 20 60 + + * - Domain + - Clock + - Purpose + * - Core (`c_clk`) + - ≤ 350 MHz + - CPU pipeline, registers, ALU, memories + * - Time (`t_clk`) + - DAC frequency (384 MHz - 6 GHz) + - Dispatcher, FIFOs, time counter, output ports + * - PS (`ps_clk`) + - 100 MHz + - AXI-Lite and AXI-Stream communication + +**Rule:** `t_clk` must be ≥ `c_clk`. Never run the core faster than the time counter. + +Related Instructions +-------------------- + +- `TIME rst` - Reset time counters +- `TIME set_ref` - Set reference time +- `TIME inc_ref` - Increment reference time +- `WAIT time @N` - Wait for specific user time +- `CLEAR` - Clear status flags (not directly time-related) + +Common Pitfalls +--------------- + +**Pitfall 1: Forgetting that `s_out_time` is signed** + +Negative values are allowed. If you accidentally write a negative time, the output will happen immediately (or when `t_abs` wraps around). + +**Pitfall 2: Back-to-back TIME instructions** + +TIME instructions cross clock domains. Do not execute two TIME instructions with less than 5 `c_clk` cycles between them. + +**Pitfall 3: FIFO overflow in tight loops** + +If you write ports faster than the dispatcher can process, the FIFO will fill and the core will stall. Monitor `s_status[14]` (FIFO_FULL). + +Related Documentation +--------------------- + +* :doc:`/tprocv2_trm` - Complete tProcessor v2 reference manual +* :doc:`/firmware` - Firmware overview and clock frequencies +* :doc:`../tprocv2_trm` - Time management section in main manual diff --git a/docs/source/topics/tutorials.rst b/docs/source/topics/tutorials.rst new file mode 100644 index 000000000..2a6fccee0 --- /dev/null +++ b/docs/source/topics/tutorials.rst @@ -0,0 +1,116 @@ +========================== +QICK Tutorials (Jupyter) +========================== + +This section contains practical tutorials for learning QICK and the tProc v2. +The tutorials are available as Jupyter notebooks and can be run directly on the RFSoC board. + +Prerequisites +============= + +- RFSoC board (ZCU111, ZCU216, or RFSoC4x2) with firmware loaded +- QICK installed (see :doc:`../quick_start`) +- Access to Jupyter notebook on the board + +Tutorials +========= + +.. toctree:: + :maxdepth: 1 + :caption: Basic Tutorials (00-05) + + ../tutorials/00_Getting_Started + ../tutorials/01_Basic_Sequencing + ../tutorials/02_Parameter_Sweeps + ../tutorials/03_Advanced_Timing + ../tutorials/04_Real_Time_Feedback + ../tutorials/05_Dynamic_Parameters_Subroutines + +.. toctree:: + :maxdepth: 1 + :caption: Intermediate Tutorials (06-09) + + ../tutorials/06_Generators_And_Readouts + ../tutorials/07_Advanced_Generators_And_Readouts + ../tutorials/08_Hardware_Buffers + ../tutorials/09_Appendix_Tips_And_Limits + +.. toctree:: + :maxdepth: 1 + :caption: Advanced Tutorials (10-14) + + ../tutorials/10_Multi_Board_Synchronization + ../tutorials/11_Streaming_And_RealTime_Processing + ../tutorials/12_DSP_Blocks_And_Correlators + ../tutorials/13_Custom_Firmware_Integration + ../tutorials/14_XCOM_Network_Synchronization + ../tutorials/README + +Running the Tutorials +===================== + +1. Connect to your RFSoC board via SSH or JupyterHub +2. Navigate to the ``docs/source/tutorials/`` directory +3. Open the desired notebook +4. **IMPORTANT**: Change the ``BITSTREAM_PATH`` variable in the first cell to point to your firmware file +5. Run the cells in order + +.. note:: + + Don't have an RFSoC board handy? Tutorials 00-07 are also available + ported to the **QICK emulator** (``QickEmu``, a Verilator-based + software simulation of the firmware) at + ``emulator/notebooks/tutorial/*_emu.ipynb`` in the + `qick repository `_, + and can be run **directly in Google Colab** with no local install -- + each notebook's first "Colab Setup" cell clones the repo and installs + Verilator for you. See the emulator's + `README `_ + for details. Each emulator notebook's intro cell notes what had to be + adapted or skipped versus the hardware original. + +Remote Execution +================ + +To run the tutorials from a remote PC: + +1. Start the proxy server on the board: ``python -m qick.pyro`` +2. In your notebook, use: ``from qick.pyro import make_proxy; soc = make_proxy("board_ip_address")`` +3. Follow the notebook instructions, replacing the local connection with the proxy connection + +Tutorial Descriptions +===================== + +Basic Tutorials +--------------- + +- **00_Getting_Started**: Connect to the board, inspect hardware configuration +- **01_Basic_Sequencing**: Define pulses, create sequences, acquire data +- **02_Parameter_Sweeps**: 1D and 2D parameter sweeps +- **03_Advanced_Timing**: ``delay`` vs ``wait``, auto-timing, avoiding collisions +- **04_Real_Time_Feedback**: Conditional pulses, active reset, thresholding +- **05_Dynamic_Parameters_Subroutines**: Virtual-Z gates, subroutines, dynamic updates + +Intermediate Tutorials +---------------------- + +- **06_Generators_And_Readouts**: Basic waveform generators, readout resonators, I/Q mixing +- **07_Advanced_Generators_And_Readouts**: Muxed generators, PFB readout, dynamic readouts, fast dynamic readout, electrical delay calibration, IQ offsets, performance benchmarks +- **08_Hardware_Buffers**: DDR4 and MR buffers, data capture +- **09_Appendix_Tips_And_Limits**: Common errors, limits, debugging tips + +Advanced Tutorials +------------------ + +- **10_Multi_Board_Synchronization**: Synchronize multiple boards using external clock and external start signals +- **11_Streaming_And_RealTime_Processing**: IQ streaming, on-FPGA averaging, real-time decimation +- **12_DSP_Blocks_And_Correlators**: FIR filters, DDS tuning, hardware correlators +- **13_Custom_Firmware_Integration**: Adding custom Verilog/VHDL, AXI-lite interface, rebuilding +- **14_XCOM_Network_Synchronization**: Full mesh network for multi-board synchronization and low-latency communication (requires FMC transceiver board) + +See Also +======== + +- :doc:`../quick_start` - Quick installation guide +- :doc:`asmv2_cheatsheet` - tProc v2 cheatsheet +- :doc:`timing` - More details on timeline management \ No newline at end of file diff --git a/docs/source/topics/units.rst b/docs/source/topics/units.rst new file mode 100644 index 000000000..8e8dbfb5e --- /dev/null +++ b/docs/source/topics/units.rst @@ -0,0 +1,66 @@ +Time units +========== + +Time durations are generally specified in units of clock cycles. +The relevant clocks are the tProcessor clock (`c_clk`) and the fabric clocks of the generators and readouts. +In general these can all be different (and can even vary among generators or readouts). + +tProcessor Time +--------------- + +The tProcessor uses a 48-bit absolute time counter (`t_abs`) that runs at the DAC clock frequency (`t_clk`). +Time values in tProc assembly (e.g., `@1000`, `@s_out_time`) are in units of `t_clk` cycles. + +**Typical clock frequencies:** + +- `t_clk` (DAC clock): 384 MHz to 6 GHz +- `c_clk` (core clock): ≤ `t_clk` (typically 350-384 MHz) + +**Conversion helpers in Python:** + +For convenience, the :meth:`.QickConfig.us2cycles()` and :meth:`.QickConfig.cycles2us()` methods convert between floating-point times and integer cycles. +You must specify which clock you are using: + +.. list-table:: Clock Selection for us2cycles() + :header-rows: 1 + :widths: 30 40 30 + + * - Parameter Type + - Use + - Example + * - Generator (pulse length, sigma) + - ``gen_ch`` (generator channel index) + - ``soccfg.us2cycles(1e-6, gen_ch=0)`` + * - Readout (acquisition length) + - ``ro_ch`` (readout channel index) + - ``soccfg.us2cycles(1e-6, ro_ch=0)`` + * - tProcessor (wait, sync, delays) + - No channel parameter + - ``soccfg.us2cycles(1e-6)`` + +**Example:** + +.. code-block:: python + + from qick import * + + soc = QickSoc() + soccfg = soc # QickSoc is itself a QickConfig, so soc has all these methods directly + + # Convert 1 microsecond to tProc cycles + tproc_cycles = soccfg.us2cycles(1e-6) + print(f"1 us = {tproc_cycles} tProc cycles") + + # Convert 1 us to generator 0 cycles + gen_cycles = soccfg.us2cycles(1e-6, gen_ch=0) + print(f"1 us = {gen_cycles} generator cycles") + +Note: tProc time values (`s_out_time`, `@time` in assembly) are **signed 32-bit integers**. +When using `us2cycles()`, ensure the result fits within ±2^31-1. + +Related Documentation +--------------------- + +* :doc:`/tprocv2_trm` - tProcessor timing model +* :doc:`/sg_v6` - Signal Generator v6 documentation +* :doc:`/readout` - Readout system documentation diff --git a/docs/source/topics/xcom.rst b/docs/source/topics/xcom.rst new file mode 100644 index 000000000..44300f3e2 --- /dev/null +++ b/docs/source/topics/xcom.rst @@ -0,0 +1,485 @@ +.. _xcom: + +XCOM: Multi-Board Network Synchronization and Communication +============================================================ + +XCOM (X - Communication) is a **full mesh network** that enables precise synchronization and low-latency communication between multiple QICK boards. This module is essential for scaling quantum control systems beyond a single RFSoC board. + +For a detailed description of the XCOM architecture and performance, refer to the XCOM paper: `arXiv:2603.18977v1 `_. + +Overview +-------- + +XCOM provides two primary capabilities: + +1. **Synchronization**: Aligns multiple QICK boards with <100 ps skew, free of drift and loss of lock +2. **Communication**: Provides deterministic, all-to-all simultaneous data exchange with latency below 185 ns (can be reduced to 62 ns) + +The XCOM network supports up to **15 boards** (prototype supports 5) and is designed to scale to large quantum computing systems. + +XCOM can be operated from: + +- **Python scripts** (via AXI-lite interface, higher latency due to Linux overhead) +- **tProc programs** (real-time operation at fabric clock speed, lowest latency) + +.. figure:: ../images/topics/fig1_xcom_block_diag.png + :align: center + :alt: XCOM Architecture + + XCOM block architecture (source: XCOM paper) + +Hardware Requirements +--------------------- + +XCOM requires additional hardware components: + +1. **FMC Transceiver Board**: A small board that plugs into the FMC connector of each ZCU216 board. It routes LVDS signals to RJ45 connectors. + +2. **External Hub**: A fanout hub that copies each transmitter's signal to all receivers, enabling full mesh connectivity. + +The current hardware prototype supports up to 5 boards, while the firmware IP already supports up to 15 boards and can be extended further. + +.. figure:: ../images/topics/fig3_fanout_box.png + :align: center + :alt: XCOM Hardware Setup + + XCOM hardware configuration (source: XCOM paper) + +Clock Domains +------------- + +The XCOM block operates across three clock domains: + +.. list-table:: + :header-rows: 1 + :widths: 15 25 60 + + * - Domain + - Source + - Description + * - ``t_clk`` + - tProc timing clock + - Fastest clock; used for high-speed serial communication + * - ``c_clk`` + - tProc core clock + - Used for command processing and state machines + * - ``ps_clk`` + - Processing System clock + - Used for AXI-lite interface to Python + +It is assumed that ``t_clk`` ≥ ``c_clk`` ≥ ``ps_clk`` in all configurations. + +Communication Protocol +---------------------- + +XCOM uses two LVDS signals for point-to-point communication, following a **Data Strobe Encoding** scheme: + +- **``xclk``** (strobe): Each change indicates a new value is present on the data line +- **``xdata``** (serial data): Carries the serialized command and data + +.. figure:: ../images/topics/xcom_waves.png + :align: center + :alt: XCOM Data Strobe Encoding + + Data strobe encoding example for 8-bit data transmission + +The ``xcom_cfg`` register's tick-config field (``i_cfg_tick``) sets the period of the strobe signal in ``t_clk`` cycles. The relationship is linear (period = 2 × (value + 1)), not a power-of-two doubling, and permitted values range from 0 to 7: + +.. list-table:: + :header-rows: 1 + :widths: 15 35 + + * - Value + - Strobe period (t_clk cycles) + * - 0 + - 2 + * - 1 + - 4 + * - 2 + - 6 + * - 3 + - 8 + * - 4 + - 10 + * - 5 + - 12 + * - 6 + - 14 + * - 7 + - 16 + +Interface Signals +----------------- + +The XCOM peripheral connects to the QICK processor via a dedicated interface with the following signals: + +.. list-table:: + :header-rows: 1 + :widths: 25 15 60 + + * - Signal + - Direction + - Description + * - ``qp_en_i`` + - Input + - Enable; activates peripheral on rising edge + * - ``qp_op_i[4:0]`` + - Input + - 5-bit operation code + * - ``qp_dt1_i[31:0]`` + - Input + - 32-bit data 1 from processor to peripheral (drives ``AXI_DT1``/``core_data1``) + * - ``qp_dt2_i[31:0]`` + - Input + - 32-bit data 2 from processor to peripheral (drives ``AXI_DT2``/``core_data2``) + * - ``qp_rdy_o`` + - Output + - Indicates peripheral ready status + * - ``qp_vld_o`` + - Output + - Marks valid data from peripheral + * - ``qp_dt1_o[31:0]`` + - Output + - Data 1 from peripheral to processor + * - ``qp_dt2_o[31:0]`` + - Output + - Data 2 from peripheral to processor + * - ``qp_flag_o`` + - Output + - Flag for inter-board signaling + +The generic QICK peripheral template (``qick_periph.sv``) actually exposes four +32-bit data inputs (``qp_dt1_i``..``qp_dt4_i``) and two 32-bit data outputs +(``qp_dt1_o``, ``qp_dt2_o``); XCOM only uses the first two inputs and both +outputs, matching its two-register (``DT1``/``DT2``) command payload. + +.. figure:: ../images/topics/xcom_periph_timing.png + :align: center + :alt: XCOM Peripheral Timing + + Peripheral interface timing diagram + +Python Interface +---------------- + +The ``QICK_Xcom`` class provides Python access to the XCOM hardware through AXI-lite registers. + +AXI Registers +~~~~~~~~~~~~~ + +.. figure:: ../images/topics/xcom_registers.png + :align: center + :alt: XCOM Registers + + XCOM AXI register map + +The following registers are available: + +.. list-table:: + :header-rows: 1 + :widths: 20 15 10 55 + + * - Register + - Address + - Access + - Description + * - ``xcom_ctrl`` + - 0 + - R/W + - Command control register + * - ``xcom_cfg`` + - 1 + - R/W + - Configuration register + * - ``axi_dt1`` + - 2 + - R/W + - Data register 1 + * - ``axi_dt2`` + - 3 + - R/W + - Data register 2 + * - ``axi_addr`` + - 4 + - R/W + - Address register + * - ``board_id`` + - 6 + - R + - Local board ID + * - ``flag`` + - 7 + - R + - Local flag status + * - ``dt1`` + - 8 + - R + - Received data 1 + * - ``dt2`` + - 9 + - R + - Received data 2 + * - ``mem`` + - 10 + - R + - Memory readback + * - ``rx_dt`` + - 12 + - R + - RX data (debug) + * - ``tx_dt`` + - 13 + - R + - TX data (debug) + * - ``status`` + - 14 + - R + - Status register + * - ``debug`` + - 15 + - R + - Debug register + +Register Control +~~~~~~~~~~~~~~~~ + +The ``XCOM_CTRL`` register is used to send commands. The ``EN`` field (``ctrl[0]``) auto-resets after one clock cycle, ensuring commands are executed only once. + +.. figure:: ../images/topics/xcom_reg_timing.png + :align: center + :alt: XCOM Control Timing + + ``XCOM_CTRL`` register timing diagram + +When ``EN`` is high: + +- ``OP_I`` (``ctrl[5:1]``) contains the command to execute +- ``AXI_DT1`` and ``AXI_DT2`` contain data for the command + +Commands +-------- + +XCOM supports two types of commands: + +- **NET commands**: Sent over the network to other boards (OP code MSB = 0) +- **LOC commands**: Executed locally, affecting only this board (OP code MSB = 1) + +NET Commands +~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 30 10 15 45 + + * - Command + - Code + - OP + - Function + * - ``XCOM_CLEAR_FLAG`` + - 0 + - 00000 + - Clear flag on remote board + * - ``XCOM_SET_FLAG`` + - 1 + - 00001 + - Set flag on remote board + * - ``XCOM_SEND_8BIT_1`` + - 2 + - 00010 + - Send 8-bit data to qp_dt1 + * - ``XCOM_SEND_8BIT_2`` + - 3 + - 00011 + - Send 8-bit data to memory + * - ``XCOM_SEND_16BIT_1`` + - 4 + - 00100 + - Send 16-bit data to qp_dt1 + * - ``XCOM_SEND_16BIT_2`` + - 5 + - 00101 + - Send 16-bit data to memory + * - ``XCOM_SEND_32BIT_1`` + - 6 + - 00110 + - Send 32-bit data to qp_dt1 + * - ``XCOM_SEND_32BIT_2`` + - 7 + - 00111 + - Send 32-bit data to memory + * - ``XCOM_QRST_SYNC`` + - 8 + - 01000 + - Synchronize with external PPS + * - ``XCOM_AUTO_ID`` + - 9 + - 01001 + - Auto-assign board ID + * - ``XCOM_UPDATE_DT8/16/32`` + - 10, 12, 14 + - 01010, 01100, 01110 + - Future use + * - ``XCOM_QCTRL`` + - 11 + - 01011 + - Control tProc state + +LOC Commands +~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 30 10 15 45 + + * - Command + - Code + - OP + - Function + * - ``XCOM_SET_ID`` + - 16 + - 10000 + - Set local board ID + * - ``XCOM_WRITE_FLAG`` + - 17 + - 10001 + - Write local flag + * - ``XCOM_WRITE_REG`` + - 18 + - 10010 + - Write to qp_dt register + * - ``XCOM_WRITE_MEM`` + - 19 + - 10011 + - Write to internal memory + * - ``XCOM_RST`` + - 31 + - 11111 + - Reset XCOM block + +For a complete reference, see :doc:`XCOM-commands`. + +tProc Control via XCOM +---------------------- + +The ``XCOM_QCTRL`` command enables remote control of tProc state. The ``DT2[2:0]`` field selects the operation: + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - DT2[2:0] + - Operation + * - 2 + - Time reset + * - 3 + - Time update + * - 4 + - Core start + * - 5 + - Core stop + * - 6 + - Processor start + * - 7 + - Processor stop + +Synchronization Protocol +------------------------ + +XCOM synchronization follows a multi-step process: + +1. **Frequency synchronization**: All boards share a common external reference clock (e.g., 100 MHz rubidium) +2. **Phase synchronization**: PLLs configured in nested zero-delay mode +3. **DAC/ADC alignment**: Multi-tile sync (MTS) calibration +4. **Absolute time alignment**: Master broadcasts RESET and START commands via ``XCOM_QRST_SYNC`` + +The synchronization sequence: + +1. Designate one board as master +2. Run ``AUTO_ID`` to assign network IDs +3. Master broadcasts ``XCOM_QRST_SYNC`` to reset absolute clocks +4. Master broadcasts ``XCOM_QCTRL`` to start all tProcs simultaneously + +This achieves <100 ps skew between boards, enabling truly synchronized multi-board experiments. + +Performance +----------- + +.. list-table:: + :header-rows: 1 + :widths: 50 50 + + * - Metric + - Value + * - Inter-board skew + - <100 ps + * - Latency (32-bit word) + - 186 ns @ 100 MHz + * - Latency (32-bit word, projected) + - 62 ns @ 312.9 MHz + * - Maximum boards + - 15 (firmware), 5 (current prototype) + * - Clock frequency + - Up to 312.9 MHz (LVDS HP I/O) + +Debugging +--------- + +The XCOM block provides extensive debug capabilities through dedicated registers. + +Status Register +~~~~~~~~~~~~~~~ + +The ``status`` register provides real-time status information: + +.. list-table:: + :header-rows: 1 + :widths: 20 15 65 + + * - Field + - Bits + - Description + * - ``tx_st`` + - [1:0] + - Transmitter state (0=IDLE, 1=WVLD, 2=WSYNC, 3=WRDY) + * - ``rx_st`` + - [8:6] + - Receiver state (0=IDLE, 1=HEADER, 2=DATA, 3=REQ, 4=ACK) + * - ``tx_ready`` + - 16 + - Transmitter ready + * - ``board_id`` + - [20:17] + - Local board ID + * - ``rx_data_cntr`` + - [24:21] + - Received data counter + +Debug Register +~~~~~~~~~~~~~~ + +The ``debug`` register exposes internal state machine signals for advanced debugging. + +Python Debug Methods +~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + # Print all AXI registers + soc.xcom_0.print_axi_regs() + + # Print status information + soc.xcom_0.print_status() + + # Print debug information + soc.xcom_0.print_debug() + +See Also +-------- + +* :doc:`XCOM-commands` — Complete command reference + +* :doc:`../tutorials/14_XCOM_Network_Synchronization` — XCOM demonstration notebook + +* `XCOM paper (arXiv:2603.18977v1) `_ + +* `QICK GitHub repository `_ diff --git a/docs/source/tprocv1.rst b/docs/source/tprocv1.rst new file mode 100644 index 000000000..f6c4277cf --- /dev/null +++ b/docs/source/tprocv1.rst @@ -0,0 +1,642 @@ +======================================================== +tProcessor v1 (axis_tproc64x32_x8) - QICK Firmware +======================================================== + +.. contents:: + :local: + :depth: 2 + +The **tProcessor v1** (``axis_tproc64x32_x8``) is the original QICK real-time +co-processor: an 8-channel, 64-bit-instruction / 32-bit-register core that +runs a user-written program to sequence pulses, trigger readouts, and react +to feedback with cycle-level timing. The module lives in the ``qick`` +firmware repository under ``firmware/ip/axis_tproc64x32_x8_v1/`` and is +exposed to Python through ``qick.drivers.tproc.AxisTProc64x32_x8``; programs +are written with ``qick.asm_v1.QickProgram``. + +.. note:: + **This is legacy hardware.** tProc v1 is still real, supported hardware -- + many older QICK boards run it, and this page documents it accurately for + that reason -- but it is **not** the recommended starting point for a new + design. New designs should use the tProcessor v2 (``qick_processor``); see + :doc:`/tprocv2_trm`. + + A few concrete, RTL-verified differences that explain why v2 superseded + v1: + + * **Instruction width / program memory.** v1 instructions are 64 bits, and + with the default ``PMEM_N=16`` parameter the usable program memory is + 2\ :sup:`13` = 8192 instructions (64 KB) -- see + :ref:`tprocv1-pmem-depth` for how that number is derived from the RTL. + v2 instructions are 72 bits, with program memory depth set independently + by the ``PMEM_AW`` parameter (default 2\ :sup:`8` = 256 words; production + designs typically configure much more). + * **Register organization.** v1 has a single flat, paged register file: 8 + pages x 32 general-purpose 32-bit registers (256 registers total, + register 0 hardwired to 0 on every page), and no separate special-purpose + register bank -- see :ref:`tprocv1-regfile`. v2 splits registers into + three purpose-built banks (general-purpose ``DREG``, special-function + ``SREG``, and waveform-parameter ``WREG``) described in + :ref:`tproc-registers` of the v2 manual. + * **Instruction set richness.** v1 has a fixed set of ~20 instructions + (see :ref:`tprocv1-isa`) covering arithmetic, bitwise ops, memory, + stack, and timed output -- there is no hardware division, no + multiply-accumulate unit, no LFSR, and no subroutine ``CALL``/``RET`` + (only an 8-bit-deep, 256-word return/data stack shared for both + ``pushi``/``popi`` and loop bookkeeping). v2 adds a division unit, a + multiply-accumulate unit, an LFSR, and a 256-deep PC-call stack (see the + v2 manual's :ref:`tproc-quick-ref`). + +-------------------------------------------------------------------- +1. General Description +-------------------------------------------------------------------- + +``axis_tproc64x32_x8`` (top-level RTL: ``axis_tproc64x32_x8.v``) wraps the +core datapath (``tproc64x32_x8.v``) together with an AXI-Lite configuration +slave (``axi_slv_custom.sv``) and a data-memory arbiter (``data_mem/``) that +lets the PS access the tProc's data memory both by single AXI-Lite +read/write and by bulk AXI-Stream DMA. + +The core itself (``tproc64x32_x8.v``) is a single-issue, microcoded processor +built from separate blocks for each function: + +* **Control FSM** (``ctrl.sv``) -- a one-hot state machine that fetches, + decodes, and sequences every instruction (most instructions take 2-4 + clock cycles; see :ref:`tprocv1-isa`). The instruction-format comments at + the top of ``ctrl.sv`` are the authoritative bit-level encoding reference + and were cross-checked against the ``instructions`` dictionary in + ``qick_lib/qick/asm_v1.py`` for this page. +* **Register file** (``regfile/regfile_8p.vhd`` + ``regfile.vhd``) -- 8 + independent 32-register banks ("pages"), selected by a 3-bit page field + in the instruction; see :ref:`tprocv1-regfile`. +* **ALU** (``alu/alu.v`` + ``math.vhd`` + ``bitw.vhd``) -- bitwise and + arithmetic operations on 32-bit operands, plus a second, independent adder + (in ``tproc64x32_x8.v``, not a separate file) dedicated to computing + absolute output times for the timed-instruction dispatcher. +* **Stack** (``stack.vhd``) -- a single 256-word x 32-bit BRAM-backed + push/pop stack, used by ``pushi``/``popi`` (and internally by ``loopnz`` + for its decrement-and-branch loop counter). +* **Per-channel timed-output dispatcher** (``fifo/fifo.vhd`` + + ``timed_ictrl.vhd``, instantiated 8x, one per output channel) -- see + :ref:`tprocv1-output`. +* **Data memory** (``bram_dp`` instance in ``axis_tproc64x32_x8.v`` + + arbiter in ``data_mem/``) -- a dual-port, 32-bit BRAM shared between the + core's own ``memr``/``memw`` instructions and PS access; see + :ref:`tprocv1-dmem`. + +The processor has: + +* **8 timed output channels** (``m1_axis`` .. ``m8_axis``, 160 bits wide + each) -- typically wired to signal generators and/or trigger/marker pins. + A 9th port pair (``s0_axis``/``m0_axis``, 32 bits) is dedicated to the + data-memory DMA path, not to timed output. +* **4 input channels** (``s1_axis`` .. ``s4_axis``, 64 bits wide each) -- + typically wired to readout feedback data, read into a register with the + ``read`` instruction. + +-------------------------------------------------------------------- +2. Synthesis Parameters +-------------------------------------------------------------------- + +.. list-table:: + :header-rows: 1 + :widths: 20 15 65 + + * - Parameter + - RTL Default + - Description + * - ``PMEM_N`` + - 16 + - Program-memory address width, in the sense of the ``pmem_addr`` output + port width. As explained in :ref:`tprocv1-pmem-depth`, the *usable* + instruction depth is 2\ :sup:`PMEM_N-3`, not 2\ :sup:`PMEM_N` -- with + the default value of 16 that is 8192 64-bit instructions (64 KB). + Exposed to Python as ``soc.tproc.PMEM_N``; the actual program-memory + *size* used by the driver, however, is read back from the + instantiated memory object's byte length + (``self.mem.mmio.length // 8``), not computed from ``PMEM_N``. + * - ``DMEM_N`` + - 10 + - Data-memory address width (log2 of the number of 32-bit words). With + the default value, data memory is 2\ :sup:`10` = 1024 samples (4 KB). + Exposed to Python as ``soc.tproc.DMEM_N`` and ``soc.tproc.cfg['dmem_size'] + = 2**DMEM_N``. + +.. note:: + An older, public copy of the firmware overview (``main_qick``'s + ``docs/firmware.rst``, explicitly flagged by that page's own PDF link as + possibly out of date) cites "4096 samples, 16 KB" for the tProc v1 data + memory -- inconsistent with the ``DMEM_N=10`` default recorded in this + repository's ``component.xml``. This is most likely a different + per-board synthesis configuration (``DMEM_N`` is a generic, so it can + legitimately differ between board builds), not an error in either + document, but it could not be verified from source in this session. + Always read ``soc.tproc.cfg['dmem_size']`` at runtime rather than + assuming a number. By contrast, that same older document's "8k + instructions / 64 KB" program-memory figure and "256 samples / 1 KB" + stack-size figure both match this session's RTL analysis exactly (see + :ref:`tprocv1-pmem-depth` and :ref:`tprocv1-regfile`). + +The AXI-Lite configuration slave (``axi_slv_custom.sv``) additionally has a +fixed, non-parameterized ``NREG = 64`` (64 x 32-bit = 256 bytes) reserved for +registers at the bottom of its address space; see :ref:`tprocv1-regmap`. + +-------------------------------------------------------------------- +3. Datapath / Architecture +-------------------------------------------------------------------- + +.. _tprocv1-pmem-depth: + +3.1. Program Memory and Program Counter +----------------------------------------- + +The program counter (``pc_r`` in ``tproc64x32_x8.v``) is a 16-bit register +that increments by 1 each fetch (``pc_i = pc_r + 1``) or is loaded with a +jump target for ``loopnz``/``condj``. Instructions are 64 bits wide and +fetched over a dedicated ``pmem_do`` bus. + +The core's ``pmem_addr`` output is ``pc_r`` directly (matching the +``PMEM_N``-bit port width when ``PMEM_N=16``). However, the top-level +wrapper (``axis_tproc64x32_x8.v``) then re-derives the *external* memory +address as:: + + assign pmem_addr = {pmem_addr_int[PMEM_N-4:0], 3'b000}; // x8 (64-bit -> byte) + +This keeps only the **low (PMEM_N-3) bits** of the program counter (13 bits +for the default ``PMEM_N=16``) and left-shifts them by 3 to form a +byte-oriented address for an 8-byte-wide (64-bit) instruction word, so the +result still fits in a ``PMEM_N``-bit bus. The top 3 bits of the 16-bit `pc_r` +are simply never forwarded to the external memory address. This is +confirmed by the testbench's program-memory BRAM instantiation +(``src/tb/tb.sv``), which drives its address port with +``{3'b000, pmem_addr[PMEM_N-1:3]}`` -- i.e. the same low 13 bits, zero-padded +back up to 16. The practical consequence: **with the default ``PMEM_N=16``, +only 2**:sup:`13` = 8192 64-bit instructions (64 KB) of program memory are +actually addressable**, regardless of the nominal 16-bit range of the PC. +This matches the driver's own comment that ``PMEM_N`` is merely "the log2 of +the number of 64-bit words, though the actual memory is usually smaller" +(``qick_lib/qick/drivers/tproc.py``), and matches the "8k instructions / 64 +KB" figure in the older public firmware overview. + +3.2. Instruction Fetch / Decode (Control FSM) +------------------------------------------------ + +``ctrl.sv`` implements a one-hot FSM with states for each instruction's +multi-cycle sequence (e.g. ``MATHI0_ST`` .. ``MATHI3_ST`` for a 4-cycle +immediate math op, ``SETI0_ST``/``SETI1_ST`` for a 2-cycle timed-output +write). Most instructions take 2-4 clock cycles to decode, operate, and +write back; instructions that push into a per-channel output FIFO +(``seti``/``set``/``setbi``/``setb``, ``waiti``/``wait``) additionally stall +in a wait state if that channel's FIFO is full (or, for the blocking +``setbi``/``setb``/``wait``/``waiti`` forms, until the dispatcher +acknowledges). + +.. _tprocv1-regfile: + +3.3. Register File +--------------------- + +The register file (``regfile/regfile_8p.vhd``, wrapping 8 instances of +``regfile.vhd``) provides **8 pages x 32 registers = 256 total 32-bit +registers**, selected by a 3-bit page field (instruction bits ``55:53``) and +5-bit register-address fields (e.g. bits ``40:36`` for ``ra``). It has 7 +parallel read ports and 1 write port, with one clock cycle of read latency; +the page-select input itself is pipelined by one cycle to stay aligned with +the muxed read data. **Register 0 on every page is hardwired to always read +0** (``regfile.vhd``: ``if unsigned(addrN) = 0 then doutN <= (others => '0')``), +which the Python driver and assembler exploit as a convenient "discard" / +"always zero" operand (e.g. in ``QickProgram``'s pulse-register allocation, +unused fields of a ``set`` call are pointed at register 0 of the page). + +3.4. ALU and Time Adder +--------------------------- + +``alu.v`` combines two sub-blocks, muxed by the top bit of the 4-bit +``oper`` field (delayed 3 cycles to match each sub-block's own pipeline +latency): + +* ``bitw.vhd`` (``oper[3]=0``): and / or / xor / not / shift-left / + shift-right. +* ``math.vhd`` (``oper[3]=1``): add / subtract / multiply. + +A second, separate adder in ``tproc64x32_x8.v`` (``alut_a + alut_b``, not +part of ``alu.v``) computes absolute output times for timed instructions: +it adds the free-running 48-bit master clock (``t_cnt_sync``, the +synchronization point most recently set by ``sync``/``synci``) to either a +register value or an immediate (selected by ``alut_src_b``), producing the +``t`` field that gets pushed into a channel's output FIFO alongside +``seti``/``set``/``waiti``/``wait``. + +3.5. Stack +------------- + +``stack.vhd`` is a single 256-word x 32-bit BRAM-backed stack (8-bit stack +pointer ``sp``, initialized to all-ones/255 on reset -- i.e. "empty"; ``full`` +is asserted when ``sp`` reaches 0). It backs ``pushi``/``popi`` directly, and +is also used internally by ``loopnz`` as its decrement-and-test loop +register mechanism is register-file-based rather than stack-based (loopnz +decrements a register, not the stack -- the stack itself is only touched by +explicit ``pushi``/``popi``). This 1 KB stack is the same figure ("256 +samples of 32 bits, 1k Byte total") given in the older public firmware +overview. + +.. _tprocv1-output: + +3.6. Timed Output Port Mechanism +------------------------------------ + +Each of the 8 output channels has its own 16-deep FIFO (``fifo/fifo.vhd``) +and its own ``timed_ictrl.vhd`` dispatcher instance. When the core executes +``seti``/``set``/``setbi``/``setb``, it packages an opcode byte, the +computed absolute output time (48 bits), and up to 5 register values (for +``set``/``setb``, corresponding to ``{re,rd,rc,rb,ra}``; for ``seti``/ +``setbi``, only one register/immediate matters) into a 216-bit word +(``FW = 5*32 + 48 + 8``) and pushes it into that channel's FIFO. + +Independently, each channel's ``timed_ictrl`` FSM continuously watches the +free-running master clock (``t_cnt``) against the timestamp at the head of +its FIFO; when the target time is reached, it drives the channel's AXI-Stream +output (``m1_axis`` .. ``m8_axis``, 160 bits wide): the low 32 bits carry a +``seti``/``setbi`` value (zero-padded to 160 bits), while a ``set``/``setb`` +drives the full 160-bit ``{p4,p3,p2,p1,p0}`` word. This is the mechanism +behind the "``p.seti()``"/"``p.set()``" style output calls referenced in the +older ASM cheatsheet: ``seti``/``set`` are non-blocking (the core only stalls +if the target FIFO is already full), while ``setbi``/``setb`` additionally +block the core until the dispatcher confirms the AXI-Stream write went out +(``m_axis_tready``). + +``waiti``/``wait`` use the same per-channel FIFO/dispatcher path, but instead +of driving an output, the dispatcher raises a ``waitt`` flag once ``t_cnt`` +reaches the target time, which the core FSM waits on (``WAIT_ACK_ST``) +before resuming -- i.e. these instructions block core execution until a +given absolute time, without touching an output port. + +3.7. Input Ports +-------------------- + +4 slave AXIS input channels (``s1_axis`` .. ``s4_axis`` at the top level, +64 bits wide) are read into a register with the R-type ``read`` instruction. +The ``oper`` field selects which half of the 64-bit input word is captured: +``oper == 4'b1010`` selects the upper 32 bits, any other value selects the +lower 32 bits (``din_i = (oper==4'b1010) ? din_mux[63:32] : din_mux[31:0]`` +in ``tproc64x32_x8.v``). + +.. _tprocv1-dmem: + +3.8. Data Memory +-------------------- + +Data memory is a dual-port 32-bit BRAM (``bram_dp``, depth 2\ :sup:`DMEM_N`). +One port is dedicated to the core's own ``memr``/``memw``/``memri``/``memwi`` +instructions. The other port is shared, through the arbiter in +``data_mem/data_mem.v``, between: + +* **Single AXI-Lite access** -- addresses above the 256-byte register window + (see :ref:`tprocv1-regmap`) map directly onto data-memory samples. +* **Bulk AXI-Stream DMA**, gated by ``MEM_MODE_REG`` (0=read from memory to + ``m0_axis``, 1=write from ``s0_axis`` to memory), ``MEM_START_REG``, + ``MEM_ADDR_REG`` (start address) and ``MEM_LEN_REG`` (sample count); the + DMA transaction runs until ``LEN_REG`` samples have moved (read side) or + ``s_axis_tlast`` is asserted (write side). + +When neither AXI-Lite single access nor an active DMA transaction is in +flight, the arbiter is idle and grants no memory port cycles beyond what the +core itself uses. + +-------------------------------------------------------------------- + +.. _tprocv1-isa: + +4. Instruction Set +-------------------------------------------------------------------- + +All instructions are 64 bits, in one of three formats (bit-field layout is +transcribed from the header comments in ``ctrl.sv`` and cross-checked +against the ``instructions`` dict in ``qick_lib/qick/asm_v1.py``): + +.. list-table:: Instruction Formats + :header-rows: 1 + :widths: 15 15 70 + + * - Format + - Bits ``63:56`` + - Remaining fields + * - I-Type + - opcode + - ``page`` (55:53), ``channel`` (52:50), ``oper`` (49:46), ``ra`` + (45:41), ``rb`` (40:36), ``rc`` (35:31), 31-bit sign-extended + ``imm`` (30:0) + * - J-Type + - opcode + - ``page`` (55:53), ``oper`` (49:46), up to 3 register fields + (45:31), 16-bit jump ``addr`` (15:0) + * - R-Type + - opcode + - ``page`` (55:53), ``channel`` (52:50), ``oper`` (49:46), up to 7 + register fields (45:6) + +.. list-table:: Instruction Set + :header-rows: 1 + :widths: 12 10 12 66 + + * - Mnemonic + - Format + - Opcode + - Description + * - ``pushi`` + - I + - ``0b00010000`` + - Push register ``ra`` (page ``p``) onto the stack; load immediate + ``imm`` into register ``rb``. + * - ``popi`` + - I + - ``0b00010001`` + - Pop the stack into register ``r`` (page ``p``). + * - ``mathi`` + - I + - ``0b00010010`` + - ``ra = rb imm``; ``op`` in ``{+, -, *}`` (``oper`` field). + * - ``seti`` + - I + - ``0b00010011`` + - Schedule register ``r`` (page ``p``) to be written to output + ``channel`` at time ``imm`` (non-blocking; see + :ref:`tprocv1-output`). + * - ``synci`` + - I + - ``0b00010100`` + - Rebase the internal time-sync reference to immediate ``imm``. + * - ``waiti`` + - I + - ``0b00010101`` + - Block the core on ``channel`` until master clock reaches ``imm``. + * - ``bitwi`` + - I + - ``0b00010110`` + - ``ra = rb imm``; ``op`` in ``{&, \|, ^, ~, <<, >>}``. + * - ``memri`` + - I + - ``0b00010111`` + - ``r = mem[imm]`` (page ``p``). + * - ``memwi`` + - I + - ``0b00011000`` + - ``mem[imm] = r`` (page ``p``). + * - ``regwi`` + - I + - ``0b00011001`` + - ``r = imm`` (page ``p``). + * - ``setbi`` + - I + - ``0b00011010`` + - Blocking variant of ``seti``. + * - ``loopnz`` + - J + - ``0b00110000`` + - If register ``r`` != 0: decrement ``r`` and jump to ``addr``; else + fall through. + * - ``condj`` + - J + - ``0b00110001`` + - Jump to ``addr`` if ``ra rb`` is true; ``op`` in + ``{>, >=, <, <=, ==, !=}`` (0-5, see the condition-code list at the + end of this section). + * - ``end`` + - J + - ``0b00111111`` + - Halt: jump to the terminal state until the tProc is restarted. + * - ``math`` + - R + - ``0b01010000`` + - ``ra = rb rc``; ``op`` in ``{+, -, *}``. + * - ``set`` + - R + - ``0b01010001`` + - Schedule 5 registers ``{re,rd,rc,rb,ra}`` (freq/phase/addr/gain/mode, + by convention) to be written to output ``channel`` at time ``rt`` + (non-blocking). + * - ``sync`` + - R + - ``0b01010010`` + - Rebase the internal time-sync reference to register ``r``. + * - ``read`` + - R + - ``0b01010011`` + - Read input ``channel`` (upper or lower 32 bits, by ``oper``) into + register ``r``. + * - ``wait`` + - R + - ``0b01010100`` + - Block the core on ``channel`` until master clock reaches register + ``r``. + * - ``bitw`` + - R + - ``0b01010101`` + - ``ra = rb rc``; ``op`` in ``{&, \|, ^, ~, <<, >>}``. + * - ``memr`` + - R + - ``0b01010110`` + - ``ra = mem[rb]``. + * - ``memw`` + - R + - ``0b01010111`` + - ``mem[rb] = ra``. + * - ``setb`` + - R + - ``0b01011000`` + - Blocking variant of ``set``. + +.. _tprocv1-condcodes: + +Math/bitwise ``op`` codes (shared 4-bit field for ``mathi``/``math``, +``bitwi``/``bitw``): ``+``\=0b1000, ``-``\=0b1001, ``*``\=0b1010 (math); +``&``\=0b0000, ``\|``\=0b0001, ``^``\=0b0010, ``~``\=0b0011, ``<<``\=0b0100, +``>>``\=0b0101 (bitwise). ``condj`` condition codes: ``>``\=0, ``>=``\=1, +``<``\=2, ``<=``\=3, ``==``\=4, ``!=``\=5 (implemented in ``cond.vhd``, +comparing registers ``ra``/``rb`` on the current page). + +-------------------------------------------------------------------- + +.. _tprocv1-regmap: + +5. Register Map +-------------------------------------------------------------------- + +The AXI-Lite configuration slave (``axi_slv_custom.sv``) reserves a fixed +64-word (256-byte) window for registers at the bottom of its address space +(``NREG = 64``); addresses at or above 256 bytes are forwarded to data +memory instead (byte-address minus 256, converted to a sample address). +Only 6 of the 64 reserved words are actually wired to anything; the rest +read/write as plain, unused storage: + +.. list-table:: + :header-rows: 1 + :widths: 22 12 12 54 + + * - Register + - Word Offset + - Byte Address + - Description + * - ``START_SRC_REG`` + - 0 + - 0x00 + - Bit 0: 0 = start from ``START_REG`` (internal), 1 = start from the + external ``start`` input pin. + * - ``START_REG`` + - 1 + - 0x04 + - Bit 0: 0 = init/stopped, 1 = start (edge-triggered: the FSM only + fires on a low-to-high transition, per the Python driver's + ``start()``, which pulses it 0 then 1). + * - ``MEM_MODE_REG`` + - 2 + - 0x08 + - Bit 0: 0 = AXIS read (memory -> ``m0_axis``), 1 = AXIS write + (``s0_axis`` -> memory). + * - ``MEM_START_REG`` + - 3 + - 0x0C + - Bit 0: 0 = stopped, 1 = execute the configured AXIS DMA operation. + * - ``MEM_ADDR_REG`` + - 4 + - 0x10 + - Starting data-memory sample address for the AXIS DMA operation. + * - ``MEM_LEN_REG`` + - 5 + - 0x14 + - Sample count for the AXIS DMA operation. + +Data memory (single-access mode) is addressed starting at byte offset 256 +(word offset 64): ``mem[addr] <-> axi_addr = 256 + 4*addr``. The Python +driver's ``single_read``/``single_write`` implement this directly as +``mmio.array[addr + NREG]`` (``NREG=64`` words). + +-------------------------------------------------------------------- + +6. Python Interface +-------------------------------------------------------------------- + +6.1. Driver (``qick.drivers.tproc.AxisTProc64x32_x8``) +---------------------------------------------------------- + +``bindto = ['user.org:user:axis_tproc64x32_x8:1.0', 'QICK:QICK:axis_tproc64x32_x8:1.0']`` +-- this identifies the v1 core in a QICK overlay's block-design metadata and +is what makes ``pynq``/``qick.QickSoc`` attach this driver class rather than +the v2 driver (``Axis_QICK_Proc``, ``bindto`` matching ``qick_processor``, +documented in :doc:`/tprocv2_trm`). It is reached as ``soc.tproc``. + +.. code-block:: python + + from qick import * + + soc = QickSoc() + tproc = soc.tproc # AxisTProc64x32_x8 instance + + # Load a compiled program (list/array of 64-bit instruction words). + tproc.load_bin_program(binprog, load_mem=True) + + # Set the start trigger source, then start. + tproc.start_src("internal") + tproc.start() + + # ... program runs in real time on the FPGA fabric ... + + # Force-stop by overwriting program memory with `end` instructions. + tproc.reset() + # Restore the program that was running before reset(). + tproc.reload_program() + +Notable methods: + +* ``start()`` -- pulses ``start_reg`` 0 then 1 (edge-triggered; has no + effect if the start source is set to external). +* ``reset()`` -- force-stops the core by overwriting **only the high 32-bit + half of every program word** (``mem.mmio.array[1::2] = 0x3F000000``) with + the ``end`` opcode (``0b00111111``, matching ``ctrl.sv``'s ``END_ST`` + encoding), leaving the low half untouched. This is a fast (~1 ms), + targeted overwrite rather than a full program-memory clear, and relies on + the opcode living in bits ``63:56`` of the 64-bit instruction word (i.e. + the high 32-bit half when the word is split for a 32-bit-wide memory + port). +* ``load_bin_program()`` / ``reload_program()`` -- write (or rewrite, after + a ``reset()``) the cached program to program memory via a direct + ``mmio`` array copy (not DMA -- program memory is memory-mapped, unlike + data memory). +* ``single_read(addr)`` / ``single_write(addr, data)`` -- single-sample AXI-Lite + access to data memory, offset by ``NREG`` (see :ref:`tprocv1-regmap`). +* ``load_dmem(buff_in, addr)`` / ``read_dmem(addr, length)`` -- bulk data-memory + transfer via the AXI-Lite/DMA arbiter (:ref:`tprocv1-dmem`): configures + ``mem_mode_reg``/``mem_addr_reg``/``mem_len_reg``/``mem_start_reg`` and + drives an AXI DMA channel. +* ``start_src(src)`` -- ``"internal"``/``"external"``, sets ``start_src_reg``. + +6.2. Assembler (``qick.asm_v1.QickProgram``) +------------------------------------------------- + +``QickProgram`` builds a program as a list of instruction dicts +(``self.prog_list``), with one Python method auto-generated per entry in the +``instructions`` class dict via ``__getattr__`` -- e.g. calling +``prog.regwi(page, reg, imm)`` looks up ``instructions['regwi']`` and calls +``append_instruction('regwi', page, reg, imm)``. This is a thin, +direct-to-bytecode assembler: ``compile()`` resolves ``label()`` targets and +packs each instruction dict into a 64-bit word per the same bit layout +documented in :ref:`tprocv1-isa`, then checks the result against +``tproccfg['pmem_size']`` (read from the driver's ``cfg['pmem_size']``, i.e. +the true, board-specific memory size -- not a hardcoded 8192). + +Register allocation is done by ``_allocate_registers()``: each generator or +tProc-controlled-readout channel is assigned a fixed block of registers +(``PULSE_REGISTERS``, 10 names such as ``freq``/``phase``/``addr``/``gain``/ +``mode``/``t``) on one of the 8 pages, packing 2 channels per page (3 if +there are more than 15 channels total), with channel 0 alone on page 0 to +leave room for loop/shot counters used by averaging program base classes. +``ch_page()``/``sreg()`` (and the ``_ro`` variants for readout channels) look +up the page and register number for a given channel/parameter name. +``safe_regwi()`` works around the 31-bit immediate limit of the ``regwi`` +I-type encoding (:ref:`tprocv1-isa`) by splitting values >= 2\ :sup:`30` +into a ``regwi`` + ``bitwi`` (shift) + optional ``mathi`` (remainder) +sequence. + +High-level helpers (``set_pulse_registers``/``pulse``, ``trigger``, +``measure``, ``sync_all``, ``wait_all``, ``reset_phase``, ...) build on top +of the raw instructions to implement the same pulse-sequencing API surface +used across QICK's higher-level ``QickProgram`` classes (v1 and v2 share +the ``AbsQickProgram``/``AcquireMixin`` base in ``qick.qick_asm``, but the +instruction-level implementation, register layout, and compiled bytecode +are entirely different between the two). + +6.3. Contrast with tProc v2 +-------------------------------- + +Where v2's ``QickProgramV2`` (``qick.asm_v2``) works with named registers +across three purpose-built banks (``r0..r31``, ``s0..s15``, ``w0..w5`` -- +see the v2 manual's :ref:`tproc-registers`) and a richer instruction set +(division, multiply-accumulate, an LFSR, subroutine calls via a 256-deep PC +stack), v1 programming is lower-level: a single flat, paged 32-register +file with no dedicated special-function registers, arithmetic limited to +add/subtract/multiply and the 6 bitwise ops in :ref:`tprocv1-isa`, and no +call/return mechanism (only the single shared push/pop stack). Timed output +in v1 always goes through the ``seti``/``set``/``setbi``/``setb`` family +described in :ref:`tprocv1-output`, addressed by output-channel number, +whereas v2 uses named wave/trigger/data ports with a page-based waveform +register bank (``r_wave``) purpose-built for signal-generator parameters. + +-------------------------------------------------------------------- + +Related Documentation +---------------------- + +* :doc:`/tprocv2_trm` -- the current tProcessor (v2), recommended for new + designs. +* :doc:`/firmware` -- system-level firmware overview (signal generators, + readout, channel assignments). +* :doc:`/avg_buffer` -- Averager + Buffer readout block, whose ``trigger`` + input is typically driven from a v1 tProc output channel bit. +* `tProcessor_64_and_Signal_Generator_V4.pdf + `_ + -- an older learning-oriented write-up of the v1 tProcessor and the + signal generator it was originally paired with. The upstream ``qick`` + repository's own firmware overview explicitly flags this PDF as **not** + up to date with the current RTL; treat it as background reading only; the + bit-level facts on this page were verified directly against the RTL and + Python driver in this repository, not against that PDF. diff --git a/docs/source/tprocv2_trm.rst b/docs/source/tprocv2_trm.rst new file mode 100644 index 000000000..4f179869a --- /dev/null +++ b/docs/source/tprocv2_trm.rst @@ -0,0 +1,5868 @@ +.. _tprocv2_trm: + +================================================== +QICK tProcessor v2 - Complete Reference Manual +================================================== + +.. meta:: + :description: Complete reference manual for the QICK tProcessor v2 real-time co-processor + +:Version: 2.2 +:Last Update: 2026-09-04 +:Compatibility: QICK Firmware (>= v0.0.1) +:Audience: Firmware developers, advanced QICK users, researchers + +.. note:: + This is the complete reference manual for the qick_processor (tProcV2). + For system-level firmware overview (signal generators, readout, channel assignments), + see :doc:`/firmware`. If you are working with older, legacy tProc v1 + hardware (``axis_tproc64x32_x8``) instead, see :doc:`/tprocv1`. + + This document was updated to match the current RTL (``firmware/rtl_lib/``). + Key corrections: parameter defaults (PMEM_AW/DMEM_AW/WMEM_AW=8, REG_AW=4, + IN_PORT_QTY=1, OUT_TRIG_QTY=2), stack depth=8 (not 256), header encodings + (010/011 internal/external peripherals, not 111), ARITH formulas + (``(A op D)*B[+/-C]``, latency 4 cycles), condition codes (bits 9:7), + s_cfg/s_ctrl bit layouts, and s_status bit map. ``w2`` is ``w_env`` + (24-bit) and ``w3`` is ``w_gain`` (32-bit) in ``r_wave`` — confirmed + against the RTL (``out_wreg_o`` truncation in ``qcore_reg_bank.sv``) and + against the field packing in ``asm_v2.py``'s ``Waveform.compile()`` + (``env`` is 3 bytes, ``gain`` is 4 bytes). The ``tprocv2_assembler.py`` + ``Alias_List`` (``w_env`` -> ``w2``, ``w_gain`` -> ``w3``) is correct as + written; there is no assembler bug. + +.. contents:: Table of Contents + :depth: 3 + +------------------------------------------------------------------------------- + +PREFACE: How to use this manual +=============================== + +This manual is organized by **task**, not just by instruction. If you know what you want to *do* (e.g., "wait for ADC data", "generate a chirp", "synchronize two boards"), look for the **task‑based section** (Chapter 9). If you need the exact encoding of an instruction, see the **reference section** (Chapter 11). + +**Conventions used in this manual:** + +.. list-table:: + :header-rows: 1 + + * - Symbol + - Meaning + * - ``[value]`` + - Optional parameter + * - ``#123`` + - Immediate (literal) value + * - ``&123`` + - Memory address + * - ``@123`` + - Time value + * - ``p0 .. p15`` + - Port number + * - ``// text`` + - Comment + * - ``> text`` + - Explanation of the preceding line + +------------------------------------------------------------------------------- + +.. _tproc-wis: + +1. What is the qick_processor (tProcV2)? (Executive Summary) +============================================================ + +The tProcessor is a **hard real‑time co‑processor** inside the QICK FPGA. It runs a user‑written program that controls waveform generation, data acquisition, and feedback with **nanosecond precision**. + +**What it does well:** + +* Generate sequences of pulses with precise timing +* React to ADC data within microseconds +* Coordinate multiple DAC/ADC channels +* Run independently of the Linux operating system + +**What it does NOT do:** + +* Floating‑point math (use fixed‑point or Python pre‑computation) +* Complex control flow (stay mostly linear with short loops) +* Interact with files or networks (that is the ARM's job) + +**Typical experiment flow:** + +:: + + +-------------+ +-------------+ +-------------+ +-------------+ + | Initialize | --> | Configure | --> | Run tProc | --> | Read back | + | board, DACs | | waveforms | | program | | results | + +-------------+ +-------------+ +-------------+ +-------------+ + ^ | | | + | v v v + Python (PS) Python/ARM tProcessor Python/ARM + (once) (pre‑compute) (real‑time) (post‑process) + +------------------------------------------------------------------------------- + +Overview +-------- + +The ``qick_processor`` (tProcV2) is a custom 32-bit data, 72-bit instruction processor +designed specifically for generating precisely timed waveforms, handling data, and +triggering events in quantum computing control systems. + +Architecture +------------ + +The processor is composed of two main blocks: + +- **CORE**: Contains the Processing Unit (``CORE_CPU``) and the Memory Unit (``CORE_MEM``). + The ``CORE_CPU`` is a 5-stage pipelined Harvard architecture executing one instruction per + clock cycle, with 18 instructions optimized for multi-operation execution. It includes a + PC-Stack supporting up to 256 nested ``CALL`` functions and a Pseudo Random Number Generator + (LFSR) for 32-bit pseudorandom number generation. + +- **DISPATCHER**: Responsible for timely port signal output. It manages three FIFOs (Wave, + Trigger, and Data), each holding specific information for output along with a designated + time. The Dispatcher continuously compares the current time against the scheduled time in + each FIFO, updating the corresponding port when the scheduled time is reached. + +Memory +------ + +``CORE_MEM`` consists of three distinct memory components: + +- **Program Memory (PMEM)**: 72-bit memory for storing instructions. +- **Data Memory (DMEM)**: 32-bit memory for user data storage. +- **WaveParam Memory (WMEM)**: 32-bit memory for storing waveform parameters to be written + to the Analog Wave Ports. + +Output Ports +------------ + +The ``qick_processor`` provides three groups of output ports: + +- **Four** 32-bit Data Ports (DPORT) +- **Thirty-two** Trigger Output Ports (TRIG) +- **Sixteen** Analog Wave Ports (WPORT) + +Special Features +---------------- + +- **Multiplication Unit (FPGA DSP)**: Performs the operation ``(D±A)*B±C`` in 2 clock cycles. +- **Division Unit (Custom)**: Provides the quotient and remainder of an integer division in + 32 clock cycles. +- **Pseudo Random Number Generator (LFSR)**: Configurable Linear Feedback Shift Register for + 32-bit pseudorandom number generation. +- **Nested CALL**: Supports function call nesting up to 256 levels. +- **Debugging Capabilities**: Step-by-step execution, time stepping, core stepping, status + reading, and debug signal output. + +AXI Interface +------------- + +The AXI stream interface is monitored by a block (``DPORT_IN Register``) that updates on +every new data reception, storing it and updating a status bit in the SREG +(``PROC_xREG``). The ``qick_processor`` exposes a set of AXI Registers (``PROC_xREG``) +that can be read and written through the AXI-Lite interface. + +Compatibility +------------- + +tProcV2 is compatible with Signal Generators of types **INT**, **Mux**, and **SGV6** +for waveform generation and output. + +------------------------------------------------------------------------------- + +.. _tproc-quick-ref: + +2. Quick Reference Card +======================= + +**Most common instructions (keep this nearby):** + +.. code-block:: text + + // Register operations + REG_WR rd imm #value // rd = value + REG_WR rd op -op(rs + #imm) // rd = rs + imm + REG_WR rd op -op(rs1 + rs2) // rd = rs1 + rs2 + + // Memory operations + REG_WR rd dmem [&addr] // rd = DMEM[addr] + DMEM_WR [&addr] imm #value // DMEM[addr] = value + + // Waveform operations + REG_WR r_wave wmem [&addr] // load waveform from WMEM + WPORT_WR pN r_wave @time // output waveform + + // Port operations + DPROT_WR pN imm value @time // output 32‑bit data + DPROT_WR pN reg rX @time // output from register + TRIG pN set @time // set trigger high + TRIG pN clr @time // set trigger low + DPORT_RD pN // read input port (to s_port_l/h) + + // Flow control + JUMP LABEL -if(condition) // conditional branch + CALL SUBROUTINE + RET + + // Waiting + WAIT time @N // wait until current time >= N + WAIT div_dt // wait for division to complete + WAIT port_dt // wait for input port data + // there is no "WAIT arith_dt" macro (unlike div_dt/port_dt/time, the + // assembler doesn't recognize it) -- poll manually, see 5.10.3 below: + TEST -op(s_status AND #h0002) -uf + JUMP HERE -if(Z) // loop while ARITH_DT_NEW (bit 1) is 0 + + // Peripherals + DIV num den // start division (32 cycles) + ARITH T rA rB // rA * rB (2 cycles) + +**Condition codes (most useful):** + +.. code-block:: text + + -if(Z) // zero (result == 0) + -if(NZ) // non‑zero (result != 0) ← most common for loops + -if(S) // negative (result < 0) + -if(NS) // non‑negative (result >= 0) + -if(F) // flag set (internal or external) + -if(NF) // flag clear + +.. list-table:: Condition Codes (bits 9:7 of the code field) + :header-rows: 1 + :widths: 12 10 18 60 + + * - Code + - Mnemonic + - Tested + - Description + * - 000 + - ``1`` (always) + - - + - Always execute + * - 001 + - ``Z`` + - ALU Z flag + - Execute if last ALU/ALU-like result was zero + * - 010 + - ``S`` + - ALU S flag + - Execute if last result was negative (sign bit set) + * - 011 + - ``NZ`` + - not(Z) + - Execute if last result was non-zero + * - 100 + - ``NS`` + - not(S) + - Execute if last result was non-negative + * - 101 + - ``F`` + - external flag_i + - Execute if flag selected by ``s_cfg.flag_src`` is high + * - 110 + - ``NF`` + - not(flag_i) + - Execute if flag is low + * - 111 + - (RFU) + - - + - Reserved for future use + +The condition codes are encoded in bits ``[9:7]`` of the 16-bit ``code`` +field (which itself is the high half of the 72-bit instruction word). + +.. list-table:: WAIT Options + :header-rows: 1 + :widths: 20 40 40 + + * - WAIT Option + - Condition Tested + - Expands To + * - ``WAIT time @N`` + - ``s_usr_time >= N`` + - TEST + JUMP loop + * - ``WAIT div_dt`` + - ``DIV_DT_NEW`` (s_status[3] == 1) + - TEST + JUMP loop + * - *(no macro)* -- ``ARITH_DT_NEW`` + - ``ARITH_DT_NEW`` (s_status[1] == 1) + - **Not a recognized WAIT macro** -- the assembler raises an error on + ``WAIT arith_dt``, unlike the other rows here. Write the TEST + JUMP + loop by hand (see :ref:`5.10.3 ` below). + * - ``WAIT port_dt`` + - Any ``PORT_DT_NEW`` bit set + - TEST + JUMP loop + +.. list-table:: CLEAR Options + :header-rows: 1 + :widths: 25 25 50 + + * - CLEAR Option + - s_ctrl Bit + - Clears + * - ``CLEAR arith`` + - 0 + - ``ARITH_DT_NEW`` + * - ``CLEAR div`` + - 1 + - ``DIV_DT_NEW`` + * - ``CLEAR qnet`` + - 2 + - ``QNET_DT_NEW`` + * - ``CLEAR qcom`` + - 3 + - ``QCOM_DT_NEW`` + * - ``CLEAR qpa`` + - 4 + - ``QPA_DT_NEW`` + * - ``CLEAR qpb`` + - 5 + - ``QPB_DT_NEW`` + * - ``CLEAR port`` + - 6 + - All ``PORT_DT_NEW`` bits + +Complete Instruction Header Reference +------------------------------------- + +.. list-table:: Instruction Headers (bits 71:69) + :header-rows: 1 + :widths: 12 28 22 42 + + * - Header + - Instruction Category + - Instructions + - Section + * - 000 + - Configuration + - NOP, TEST + - 5.15 + * - 001 + - Branch + - JUMP, CALL, RET + - 5.16 + * - 010 + - Internal Peripheral Control + - TIME, FLAG, ARITH, DIV + - 5.8 + * - 011 + - External Peripheral Control + - NET, COM, PA, PB + - 5.8 + * - 100 + - Register Write + - REG_WR + - 5.14 + * - 101 + - Memory Write + - DMEM_WR, WMEM_WR + - 5.13 + * - 110 + - Port I/O + - DPORT_WR, TRIG, WPORT_WR, DPORT_RD + - 5.12 + * - 111 + - Reserved + - - + - - + +------------------------------------------------------------------------------- + +3. Architecture Deep Dive +========================= + +3.1. Block Diagram with Data Flow +--------------------------------- + +The diagram below shows how data moves through the tProcessor. Follow the arrows to understand pipeline stages. + +:: + + +=======================================================================+ + || PS (ARM) || + || +-------------------+ +-------------------+ || + || | Python script | | DMA controller | || + || | (notebook, CLI) |<-->| (AXI master) | || + || +---------+---------+ +---------+---------+ || + || | | || + +=============|========================|================================+ + | | + | (AXI‑Lite) | (AXI‑Stream, DMA) + v v + +=======================================================================+ + || tProcessor || + || || + || +------------------+ +---------------------------------------+ || + || | AXI_REG bank | | Dispatcher (t_clk domain) | || + || | * tproc_ctrl | | | || + || | * tproc_cfg | | +--------+ +--------+ +-----+ | || + || | * core_cfg | | | WFIFO | | DFIFO | | TFIFO| | || + || | * src_dt | | |(168b) | | (32b) | | (1b) | | || + || +------------------+ | +---+----+ +---+----+ +--+--+ | || + || | | | | | | || + || v | v v v | || + || +==================+ | +-------+ +-------+ +-------+ | || + || || CORE (c_clk) || | | 48‑bit| | 48‑bit| | 48‑bit| | || + || || || | |compar | |compar | |compar | | || + || || +-----------+ || | | & | | & | | & | | || + || || | 5‑stage | || | +---+---+ +---+---+ +---+---+ | || + || || | pipeline | || | | | | | || + || || | * Fetch | || | v v v | || + || || | * Decode | || | +-------+ +-------+ +-------+ | || + || || | * Read | || | | WPORT | | DPORT | | TRIG | | || + || || | * Execute | || | | (analog| | (digital| | (1‑bit| | || + || || | * Write | || | | wave) | | data) | | out) | | || + || || +-----------+ || | +---+---+ +---+---+ +---+---+ | || + || || | || | | | | | || + || || v || +======|============|============|======+ || + || || +----+----+ || v v v || + || || | ALU | || [DACs] [PMODs] [Triggers] || + || || | (DSP) | || || + || || +----+----+ || || + || || | || || + || || v || || + || || +----+----+ || || + || || | DIV | || || + || || | (32 cyc)| || || + || || +----+----+ || || + || || | || || + || || v || || + || || +----+----+ || || + || || | LFSR | || || + || || |(PRNG) | || || + || || +---------+ || || + || || || || + || || +-----------+ || || + || || | Memories | || || + || || | * PMEM | || || + || || | * DMEM | || || + || || | * WMEM | || || + || || +-----------+ || || + || +==================+ || + || || + || +------------------+ || + || | IN_PORT (AXI‑S) | <─── from ADC or external source || + || | (feedback data) | || + || +------------------+ || + +=======================================================================+ + +3.2. Clock Domain Crossing (CDC) Explained +------------------------------------------- + +Because the core and the dispatcher run on different clocks, any communication between them must cross clock domains. This introduces **latency** and **metastability protection**. + +**Critical paths and their latencies:** + +.. list-table:: + :header-rows: 1 + + * - Action + - From domain + - To domain + - Latency (cycles of destination clock) + * - Write to FIFO (DPORT_WR) + - c_clk + - t_clk + - 2‑3 cycles + * - FIFO pop to output pin + - t_clk + - t_clk (same) + - 1 cycle + * - Read input port (DPORT_RD) + - t_clk (ADC) + - c_clk + - 2‑3 cycles + * - TIME instruction effect + - c_clk + - t_clk + - 3‑5 cycles + * - FLAG from Python to core + - ps_clk + - c_clk + - several µs (not for tight timing) + +**Practical implication:** Do not back‑to‑back TIME instructions without at least 5 c_clk cycles between them. + +**proc_start / proc_stop CDC:** In the packaged IP top (`qick_processor.sv`), `proc_start_i` and `proc_stop_i` are synchronized from `ps_clk_i` into `c_clk_i` via `cdc_reg_sync` and then edge-detected into one-shot pulses before reaching `tprocv2`. This mirrors the pulse-from-level handling in `qproc_ctrl` for `PS_TPROC_CTRL`. + +3.3. FIFO Depth and Flow Control +-------------------------------- + +The dispatcher has three independent FIFOs: + +.. list-table:: + :header-rows: 1 + + * - FIFO + - Entry width + - Default depth + - Configurable up to + - When is it written? + * - Wave FIFO (WFIFO) + - 168 bits + 48 bits time + - 8 + - 512 + - WPORT_WR + * - Data FIFO (DFIFO) + - 32 bits + 48 bits time + - 8 + - 512 + - DPORT_WR + * - Trigger FIFO (TFIFO) + - 1 bit + 48 bits time + - 8 + - 512 + - TRIG + +**Flow control behavior:** + +When a FIFO becomes full: + +- If ``tproc_cfg[10]`` (``DISABLE_FIFO_FULL_PAUSE``) = 0 (default): The core **stalls** (pauses) until space is available. +- If = 1: The core continues, but writes to the full FIFO are **dropped** (data loss). + +**Checklist for avoiding FIFO overflow:** + +- [ ] Count how many port writes you have in the shortest time window. +- [ ] Ensure that number ≤ FIFO depth. +- [ ] If you need more, increase FIFO depth in the hardware configuration (Chapter 10). +- [ ] Or add ``WAIT fifo_not_full`` (macro) before writes. + +3.4. Pipeline Stages and Hazards +-------------------------------- + +The tProcessor uses a 5-stage pipeline. Understanding it helps avoid performance issues. + +**Pipeline Stages:** + +The tProcessor uses a 5-stage pipeline: + +.. code-block:: text + + Cycle: 1 2 3 4 5 + ──────────────────────────────────── + Inst1: FETCH DECODE READ EXEC WRITE + Inst2: FETCH DECODE READ EXEC + Inst3: FETCH DECODE READ + Inst4: FETCH DECODE + Inst5: FETCH + + +**Branch Penalty:** + +When a branch is taken, the pipeline flushes, causing a **2-cycle penalty**. + +**Load-Use Hazard:** + +Reading a register immediately after writing may cause a 1-cycle stall. + +**Dual Task Hazard Prevention:** + +In dual task instructions, both operations read **original** register values. +Writes happen at the end of the cycle - no hazard. + +3.5. Interrupts (Important Limitation) +-------------------------------------- + +.. warning:: + The tProcessor v2 **does NOT support interrupts**. + +This is intentional for deterministic real-time behavior. + +**Alternatives for event response:** + +- Use ``WAIT`` macro (polls status register) +- Use short loops and check flags frequently +- Python can set external flags that tProc polls + + +------------------------------------------------------------------------------- + +.. _tproc-registers: + +4. Complete Register Bank Reference +==================================== + +The tProcessor has three independent register banks. Each bank has a different purpose and access method. + +4.1. Register Organization Overview +------------------------------------ + +The diagram below shows the physical organization of all registers: + +:: + + ╔══════════════════════════════════════════════════════════════════════════════╗ + ║ REGISTER BANKS (total 32+16+6 registers) ║ + ╠══════════════════════════════════════════════════════════════════════════════╣ + ║ ║ + ║ ┌─────────────────────────────┐ ┌──────────────────────────────┐ ║ + ║ │ DREG (Data Registers) │ │ SREG (Special Function) │ ║ + ║ │ ┌─────┬─────────────┐ │ │ ┌─────┬─────────────────┐ │ ║ + ║ │ │ r0 │ general │ │ │ │ s0 │ s_zero (always0)│ │ ║ + ║ │ │ r1 │ purpose │ │ │ │ s1 │ s_rand (LFSR) │ │ ║ + ║ │ │ r2 │ 32-bit │ │ │ │ s2 │ s_cfg / s_ctrl │ │ ║ + ║ │ │ ... │ registers │ │ │ │ s3 │ s_arith_low │ │ ║ + ║ │ │ r31 │ │ │ │ │ s4 │ s_div_q │ │ ║ + ║ │ └─────┴─────────────┘ │ │ │ s5 │ s_div_r │ │ ║ + ║ │ │ │ │ s6 │ s_core_r1 │ │ ║ + ║ │ Access: REG_WR rd ... │ │ │ s7 │ s_core_r2 │ │ ║ + ║ │ Example: REG_WR r5 imm #10 │ │ │ s8 │ s_port_l │ │ ║ + ║ └─────────────────────────────┘ │ │ s9 │ s_port_h │ │ ║ + ║ │ │ s10 │ s_status │ │ ║ + ║ ┌─────────────────────────────┐ │ │ s11 │ s_usr_time │ │ ║ + ║ │ WREG (Wave Param Registers)│ │ │ s12 │ s_core_w1 │ │ ║ + ║ │ ┌─────────┬──────────────┐ │ │ │ s13 │ s_core_w2 │ │ ║ + ║ │ │ w0 │ w_freq (32b)│ │ │ │ s14 │ s_out_time │ │ ║ + ║ │ │ w1 │ w_phase (32b)│ │ │ │ s15 │ s_addr │ │ ║ + ║ │ │ w2 │ w_env (24b)│ │ │ └─────┴─────────────────┘ │ ║ + ║ │ │ w3 │ w_gain (32b)│ │ │ │ ║ + ║ │ │ w4 │ w_length(32b)│ │ │ Access: REG_WR sX ... │ ║ + ║ │ │ w5 │ w_conf (16b)│ │ │ Example: REG_WR s10 op -op()│ ║ + ║ │ └─────────┴──────────────┘ │ └──────────────────────────────┘ ║ + ║ │ │ ║ + ║ │ These 6 registers are │ ║ + ║ │ concatenated to form │ ║ + ║ │ the 168-bit r_wave bus: │ ║ + ║ │ │ ║ + ║ │ r_wave = {w5, w4, w3, │ ║ + ║ │ w2, w1, w0} │ ║ + ║ │ │ ║ + ║ │ Access: REG_WR wX ... │ ║ + ║ │ Example: REG_WR w_freq imm │ ║ + ║ └─────────────────────────────┘ ║ + ║ ║ + ╚══════════════════════════════════════════════════════════════════════════════╝ + + +4.2. Physical Address Map +------------------------- + +Each register has a physical address used internally. You don't need this for assembly +programming (use names like ``r5``, ``s10``, ``w_freq``), but it's useful for debugging +or when reading the AXI debug registers. + +.. list-table:: Register Physical Addresses + :header-rows: 1 + :widths: 15 15 20 50 + + * - Bank + - Address Range + - Number + - Assembly Names + * - SREG + - 0x00 - 0x0F + - 16 + - ``s0`` ... ``s15`` (plus aliases) + * - DREG + - 0x10 - 0x1F + - 32 + - ``r0`` ... ``r31`` + * - WREG (wave params) + - 0x20 - 0x25 + - 6 + - ``w0`` (w_freq), ``w1`` (w_phase), ``w2`` (w_env), ``w3`` (w_gain), ``w4`` (w_length), ``w5`` (w_conf) + * - Special (r_wave) + - (virtual) + - 1 + - ``r_wave`` (168-bit concatenation of all wregs) + +4.3. Complete Register Table with Aliases +------------------------------------------ + +**DREG - Data Registers (r0 - r31)** + +These are general purpose. No predefined aliases, but you can create your own: + +.. code-block:: text + + .ALIAS loop_counter r0 + .ALIAS temp_result r1 + .ALIAS dmem_ptr r2 + +**SREG - Special Function Registers (s0 - s15)** + +.. list-table:: + :header-rows: 1 + :widths: 10 25 15 50 + + * - Address + - Assembly Name + - Aliases + - Description / Typical Use + * - 0x00 + - ``s0`` + - ``s_zero`` + - Always reads as 0. Useful for clearing or as a source. + * - 0x01 + - ``s1`` + - ``s_rand`` + - Pseudo-random number from LFSR. Configurable behavior via core_cfg. + * - 0x02 + - ``s2`` + - ``s_cfg`` (lower byte), ``s_ctrl`` (upper byte, one-shot) + - Configuration: data sources, flag sources. ``s_ctrl`` self-clears the cycle after it is written (one-shot). + * - 0x03 + - ``s3`` + - ``s_arith_low`` + - Lower 32 bits of ARITH (multiply) result. + * - 0x04 + - ``s4`` + - ``s_div_q`` + - Quotient from DIV operation. + * - 0x05 + - ``s5`` + - ``s_div_r`` + - Remainder from DIV operation. + * - 0x06 + - ``s6`` + - ``s_core_r1`` + - First data word from selected source (see s_cfg DT_SRC). + * - 0x07 + - ``s7`` + - ``s_core_r2`` + - Second data word from selected source. + * - 0x08 + - ``s8`` + - ``s_port_l`` + - Lower 32 bits of input port read (DPORT_RD). + * - 0x09 + - ``s9`` + - ``s_port_h`` + - Upper 32 bits of input port read (DPORT_RD). + * - 0x0A + - ``s10`` + - ``s_status`` + - Status flags: peripherals ready, new data, FIFO state. + * - 0x0B + - ``s11`` + - ``s_usr_time``, ``curr_usr_time`` + - Current user time (read-only). t_abs - t_ref. + * - 0x0C + - ``s12`` + - ``s_core_w1`` + - First data word written from PS (ARM) to core. + * - 0x0D + - ``s13`` + - ``s_core_w2`` + - Second data word written from PS to core. + * - 0x0E + - ``s14`` + - ``s_out_time``, ``out_usr_time`` + - Output time register for port writes (read/write, 32-bit). + * - 0x0F + - ``s15`` + - ``s_addr`` + - Address register for JUMP instructions. + +**Note on addressing:** the register page is selected by ``w_addr_i[6:5]``. ``2'b00`` selects the SREG page (addresses ``0x00..0x0F``), ``2'b01`` selects the DREG page (``0x10..0x1F``), ``2'b10`` selects the WREG page (``0x20..0x25``). Assembly names map ``s0..s15`` -> ``0x00..0x0F``, ``r0..r31`` -> ``0x10..0x2F``, ``w0..w5`` -> ``0x20..0x25``. + +**WREG - Wave Parameter Registers (w0 - w5)** + +These six registers are **individually accessible** but also concatenated into ``r_wave``. + +.. list-table:: + :header-rows: 1 + :widths: 10 15 15 15 45 + + * - Address + - Base Name + - Alias + - Bits + - Description + * - 0x20 + - ``w0`` + - ``w_freq`` + - 32 + - Frequency control word for DDS. 0 = DC, 2^31 = Nyquist. + * - 0x21 + - ``w1`` + - ``w_phase`` + - 32 + - Phase offset. 2^32 = 360 degrees. + * - 0x22 + - ``w2`` + - ``w_env`` + - 24 + - Starting address in envelope table memory. + * - 0x23 + - ``w3`` + - ``w_gain`` + - 32 + - Amplitude scaling. Signed 32-bit integer. + * - 0x24 + - ``w4`` + - ``w_length`` + - 32 + - Envelope length in samples. + * - 0x25 + - ``w5`` + - ``w_conf`` + - 16 + - Configuration bits for signal generator. + +**Special Composite: r_wave** + +.. code-block:: text + + r_wave is not a physical register. It is a 168-bit bus formed by concatenation: + + r_wave = { w5 (w_conf), w4 (w_length), w3 (w_gain), + w2 (w_env), w1 (w_phase), w0 (w_freq) } + + Bits: 167:152 = w_conf (16 bits, w5) + 151:120 = w_length (32 bits, w4) + 119:88 = w_gain (32 bits, w3) + 87:64 = w_env (24 bits, w2[23:0]) + 63:32 = w_phase (32 bits, w1) + 31:0 = w_freq (32 bits, w0) + + You can write to ``r_wave`` using ``REG_WR r_wave ...``, which updates **all six** wave parameters at once. + +4.4. Access Examples by Register Type +-------------------------------------- + +**Writing to DREG (data registers):** + +.. code-block:: text + + REG_WR r5 imm #100 // r5 = 100 + REG_WR r5 op -op(r0 + r1) // r5 = r0 + r1 + REG_WR r5 dmem [&10] // r5 = DMEM[10] + +**Reading from DREG (as source):** + +.. code-block:: text + + REG_WR r6 op -op(r5) // r6 = r5 (copy) + DMEM_WR [&20] imm r5 // DMEM[20] = r5 + DPROT_WR p0 reg r5 @100 // output r5 to port + +**Writing to SREG:** + +.. code-block:: text + + REG_WR s_cfg imm src_arith // configure data source + REG_WR s_out_time imm #1000 // set output time + REG_WR s_addr label LOOP // store jump address + +**Reading from SREG:** + +.. code-block:: text + + REG_WR r0 op -op(s_rand) // r0 = random number + REG_WR r1 op -op(s_usr_time) // r1 = current time + REG_WR r2 op -op(s_status) // r2 = status bits + +**Writing to WREG (individual parameter):** + +.. code-block:: text + + REG_WR w_freq imm #0x1000000 // set frequency + REG_WR w_gain imm #32768 // set gain + REG_WR w_length imm #1000 // set length + +**Writing to r_wave (all parameters at once):** + +.. code-block:: text + + REG_WR r_wave wmem [&5] // load from WMEM + // or + REG_WR r_wave imm #0x... // immediate (not practical, too large) + +**Using wreg as source in ALU operations:** + +.. code-block:: text + + REG_WR r0 op -op(w_freq) // r0 = current frequency + REG_WR r1 op -op(w_freq + #100) // r1 = frequency + 100 + +4.5. Flag Register (not memory-mapped) +-------------------------------------- + +The tProcessor has an **internal flag** (IF) and can also use an **external flag** (EF) set from Python. + +.. list-table:: + :header-rows: 1 + + * - Flag + - Set by + - Cleared by + - Test with + * - Internal Flag (IF) + - ``FLAG set``, or automatically by peripherals + - ``FLAG clr`` + - ``-if(F)``, ``-if(NF)`` + * - External Flag (EF) + - Python (tproc_ctrl bit 13) + - Python (tproc_ctrl bit 14) + - ``-if(F)``, ``-if(NF)`` (if configured) + +Which flag is used by ``-if(F)`` is determined by ``s_cfg[7:4]`` (FLAG_SRC). + +4.6. Detailed Bit Field Definitions +------------------------------------ +.. _s_cfg_details: + +s_cfg - Configuration Register (Lower 8 bits of s2) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This register controls data routing and flag selection. Write using ``REG_WR s_cfg imm ``. + +**Bit Fields:** + +.. list-table:: + :header-rows: 1 + :widths: 10 15 15 60 + + * - Bits + - Field + - Assembler Aliases + - Description + * - 3:0 + - ``DT_SRC`` + - ``src_axi``, ``src_arith``, ``src_qnet``, etc. + - Selects source for ``s_core_r1`` (s6) and ``s_core_r2`` (s7). + + * 0x0 (``src_axi``): Reads Python-written data (``TPROC_W_DT1/2``). + * 0x1 (``src_arith``): Reads ARITH result (lower 32 bits). + * 0x2 (``src_qnet``): Reads QNET input data. + * 0x3 (``src_qcom``): Reads QCOM input data. + * 0x4 (``src_qpa``): Reads QP1 input data. + * 0x5 (``src_qpb``): Reads QP2 input data. + * 0x6 (``src_core``): Reads the other core's ``CORE_W_DT``. + * 0x7 (``src_port``): Reads the input port data (``DPORT_RD``). + * - 7:4 + - ``FLAG_SRC`` + - ``flg_int``, ``flg_axi``, ``flg_ext``, ``flg_div``, etc. + - Selects the flag source for conditional execution ``-if(F)``. + + * 0x0 (``flg_int``): Internal Flag. + * 0x1 (``flg_axi``): AXI Flag (set/cleared by PS via ``tproc_ctrl``). + * 0x2 (``flg_ext``): External Flag (``ext_flag_i``). + * 0x3 (``flg_div`` / ``flg_arith``): ``ARITH_DT_NEW | DIV_DT_NEW``. + * 0x4 (``flg_port``): Any ``PORT_DT_NEW`` bit set. + * 0x5 (``flg_qnet``): QNET ``flag_i``. + * 0x6 (``flg_qcom``): QCOM ``flag_i``. + * 0x7 (``flg_qpa``): QP1 ``flag_i``. + +s_ctrl - Clear Flags Register (Upper 8 bits of s2) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Write **'1'** to clear the corresponding ``_NEW`` flag in ``s_status``. The bit self-clears the cycle after it is written (one-shot). + +**Bit Fields:** + +.. list-table:: + :header-rows: 1 + :widths: 10 15 15 60 + + * - Bits (in byte) + - Field + - Assembler Aliases + - Description + * - 0 + - ``arith_clr`` + - ``clr_arith`` + - Clears ``ARITH_DT_NEW`` (bit 1 of ``s_status``). + * - 1 + - ``div_clr`` + - ``clr_div`` + - Clears ``DIV_DT_NEW`` (bit 3 of ``s_status``). + * - 2 + - ``qnet_clr`` + - ``clr_qnet`` + - Clears ``QNET_DT_NEW`` (bit 5 of ``s_status``). + * - 3 + - ``qcom_clr`` + - ``clr_qcom`` + - Clears ``QCOM_DT_NEW`` (bit 7 of ``s_status``). + * - 4 + - ``qpa_clr`` + - ``clr_qpa`` + - Clears ``QPA_DT_NEW`` (bit 9 of ``s_status``). + * - 5 + - ``qpb_clr`` + - ``clr_qpb`` + - Clears ``QPB_DT_NEW`` (bit 11 of ``s_status``). + * - 6 + - ``port_clr`` + - ``clr_port`` + - Clears all ``PORT_DT_NEW`` bits (bits 31:16 of ``s_status``). + +s_status - Status Register (Read-Only, s10) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +**Bit Fields:** + +.. list-table:: + :header-rows: 1 + :widths: 10 15 15 60 + + * - Bit + - Name + - Assembler Mask + - Description + * - 0 + - ``ARITH_RDY`` + - ``#1`` + - Arithmetic unit is ready/idle (high when not working). + * - 1 + - ``ARITH_DT_NEW`` + - ``#2`` + - New arithmetic result available. Clear via ``CLEAR arith`` or reading ``s_arith_low``. + * - 2 + - ``DIV_RDY`` + - ``#4`` + - Divider unit is ready. + * - 3 + - ``DIV_DT_NEW`` + - ``#8`` + - New division result available. Clear via ``CLEAR div`` or reading ``s_div_q``/``s_div_r``. + * - 4 + - ``QNET_RDY`` + - ``#0x10`` + - QNET peripheral is ready for a new transaction. + * - 5 + - ``QNET_DT_NEW`` + - ``#0x20`` + - New data from QNET received. Clear via ``CLEAR qnet`` or reading ``s_core_r1``/``s_core_r2`` with ``DT_SRC=src_qnet``. + * - 6 + - ``QCOM_RDY`` + - ``#0x40`` + - QCOM peripheral is ready. + * - 7 + - ``QCOM_DT_NEW`` + - ``#0x80`` + - New data from QCOM received. Clear via ``CLEAR qcom``. + * - 8 + - ``QPA_RDY`` + - ``#0x100`` + - QP1 peripheral is ready. + * - 9 + - ``QPA_DT_NEW`` + - ``#0x200`` + - New data from QP1 received. Clear via ``CLEAR qpa``. + * - 10 + - ``QPB_RDY`` + - ``#0x400`` + - QP2 peripheral is ready. + * - 11 + - ``QPB_DT_NEW`` + - ``#0x800`` + - New data from QP2 received. Clear via ``CLEAR qpb``. + * - 12 + - ``RFU`` + - ``#0x1000`` + - Reserved (always 0). + * - 13 + - ``RFU`` + - ``#0x2000`` + - Reserved (always 0). + * - 14 + - ``FIFO_FULL`` + - ``#0x4000`` + - At least one dispatcher FIFO is full. + * - 15 + - ``ANY_PORT_NEW`` + - ``#0x8000`` + - Any input port has new data (OR of ``PORT_DT_NEW[15:0]``). + * - 31:16 + - ``PORT_DT_NEW`` + - ``#0xFFFF0000`` + - **Bit mask per input port**. Bit 16 corresponds to Port 0. Set when new data arrives via ``DPORT_RD``. Clear via ``CLEAR port``. + +.. _core_cfg_details: + +core_cfg - LFSR Configuration (AXI Register 0x07) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Controls the behavior of the Pseudo-Random Number Generator (LFSR) connected to ``s_rand``. + +**Bit Fields:** + +.. list-table:: + :header-rows: 1 + :widths: 10 25 60 + + * - Bits + - Value (CFG) + - Description + * - 1:0 + - ``0`` (STOP) + - LFSR stops. The value in ``s_rand`` remains constant. + * - 1:0 + - ``1`` (FREE_RUN) + - LFSR advances **every** `c_clk` cycle. Fastest random updates. + * - 1:0 + - ``2`` (READ_STEP) + - LFSR advances **only when** the core reads the ``s_rand`` register. + * - 1:0 + - ``3`` (WRITE_STEP) + - LFSR advances **only when** the core writes to the ``s_rand`` register (value is discarded). + +4.7. Peripherals Control & Status Registers +-------------------------------------------- + +Each peripheral (ARITH, DIV, TIME, FLAG) has a specific control and status interface. +The table below summarizes the registers involved: + +.. list-table:: Peripheral Register Map + :header-rows: 1 + :widths: 30 30 30 35 + + * - Peripheral + - Control Register + - Status Register + - Data Register + * - ARITH (Multiply) + - Instruction only (no control reg) + - ``s_status[0]`` (RDY), ``s_status[1]`` (NEW) + - ``s_arith_low`` (s3) + * - DIV (Divide) + - Instruction only + - ``s_status[2]`` (RDY), ``s_status[3]`` (NEW) + - ``s_div_q`` (s4), ``s_div_r`` (s5) + * - TIME (Time control) + - ``TIME`` instruction + - (none) + - ``s_usr_time`` (s11), ``s_out_time`` (s14) + * - FLAG (Internal) + - ``FLAG`` instruction + - (none) + - (none - just the flag bit) + * - LFSR (Random) + - ``core_cfg`` (AXI) + - (none) + - ``s_rand`` (s1) + +4.7.1. ARITH (Multiply-Accumulate) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ARITH peripheral is started by an instruction, not by writing a register. + +**Control Flow:** + +.. code-block:: text + + // 1. Start operation + ARITH PTP r1 r2 r3 r4 // (r1+r2)*r3+r4 + + // 2. Wait for completion (poll s_status -- no WAIT macro for this, see 5.10.3) + TEST -op(s_status AND #h0002) -uf + JUMP HERE -if(Z) // loops until bit 1 (ARITH_DT_NEW) is set + + // 3. Read result + REG_WR r5 op -op(s_arith_low) + + // 4. Clear new-data flag (optional) + CLEAR arith // macro: writes s_ctrl[16]=1 + +**Status Bits (s_status):** + +.. list-table:: + :header-rows: 1 + :widths: 20 20 60 + + * - Bit + - Name + - Description + * - 0 + - ``ARITH_RDY`` + - Set when ARITH is idle. Cleared when operation starts. + * - 1 + - ``ARITH_DT_NEW`` + - Set when result is ready. Cleared by reading or ``CLEAR arith``. + +**Data Register:** + +- ``s_arith_low`` (s3): Lower 32 bits of the 64-bit result. +- The upper 32 bits are NOT accessible in this version. + +**Control Register: None** - The ARITH unit has no memory-mapped control register. +All configuration is done via the instruction opcode. + +4.7.2. DIV (Integer Division) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +**Control Flow:** + +.. code-block:: text + + // 1. Start division + DIV r1 r2 // r1 / r2 (unsigned) + + // 2. Do other work while division runs (32 cycles) + REG_WR r3 op -op(r3 + #1) + + // 3. Wait for completion + WAIT div_dt + + // 4. Read results + REG_WR r4 op -op(s_div_q) // quotient + REG_WR r5 op -op(s_div_r) // remainder + + // 5. Clear flag + CLEAR div + +**Status Bits (s_status):** + +.. list-table:: + :header-rows: 1 + :widths: 20 20 60 + + * - Bit + - Name + - Description + * - 2 + - ``DIV_RDY`` + - Set when DIV is idle. Cleared when division starts. + * - 3 + - ``DIV_DT_NEW`` + - Set when result is ready. Cleared by reading or ``CLEAR div``. + +**Data Registers:** + +- ``s_div_q`` (s4): 32-bit quotient (unsigned). +- ``s_div_r`` (s5): 32-bit remainder (unsigned). + +**Important Notes:** + +- Division is **unsigned only**. For signed division, convert to positive values. +- Denominator cannot be zero (undefined behavior). +- Takes exactly 32 cycles to complete (plus pipeline overhead). + +4.7.3. TIME (Time Control Peripheral) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The TIME peripheral is controlled by dedicated instructions, not by memory-mapped registers. + +**Instructions:** + +.. list-table:: + :header-rows: 1 + :widths: 20 30 50 + + * - Instruction + - Example + - Effect + * - ``TIME rst`` + - ``TIME rst`` + - ``t_abs = 0``, ``t_ref = 0``, reset core + * - ``TIME set_ref rX`` + - ``TIME set_ref r0`` + - ``t_ref = rX`` (t_abs unchanged) + * - ``TIME inc_ref #N`` + - ``TIME inc_ref #100`` + - ``t_ref = t_ref + N`` + * - ``TIME updt #N`` + - ``TIME updt #10`` + - ``t_abs = t_abs + N`` (rarely used) + +**Internal Time Registers (not directly accessible):** + +.. list-table:: + :header-rows: 1 + :widths: 20 20 60 + + * - Register + - Width + - Description + * - ``t_abs`` + - 48 bits + - Absolute time counter. Runs at DAC clock (`t_clk`). + * - ``t_ref`` + - 48 bits + - Reference time offset. Defines where user time = 0. + * - ``t_usr`` + - 32 bits (read via s11) + - User time = `t_abs - t_ref` (truncated to 32 bits). + +**Time-Related SREG Registers:** + +.. list-table:: + :header-rows: 1 + :widths: 15 20 20 45 + + * - Register + - Alias + - Access + - Description + * - s11 + - ``s_usr_time`` + - Read-only + - Current user time (32 bits of `t_abs - t_ref`) + * - s14 + - ``s_out_time`` + - Read/Write + - Output time for next port write (signed 32-bit) + +**Clock Domain Crossing Warning:** + +The TIME instruction crosses from `c_clk` to `t_clk` domain. +Do **not** execute two TIME instructions with less than 5 cycles between them. + +4.7.4. FLAG (Internal Flag) +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The internal flag is a single bit that can be used for conditional execution. + +**Instructions:** + +.. list-table:: + :header-rows: 1 + :widths: 20 30 50 + + * - Instruction + - Example + - Effect + * - ``FLAG set`` + - ``FLAG set`` + - Sets internal flag to 1. + * - ``FLAG clr`` + - ``FLAG clr`` + - Clears internal flag to 0. + * - ``FLAG inv`` + - ``FLAG inv`` + - Toggles internal flag (0→1, 1→0). + +**Usage with Conditional Execution:** + +.. code-block:: text + + FLAG set // set flag + REG_WR r0 imm #100 -if(F) // executed (flag=1) + FLAG clr + REG_WR r1 imm #200 -if(F) // NOT executed (flag=0=NF) + +**Note:** The flag used by `-if(F)` can be configured via `s_cfg[7:4]` (FLAG_SRC) to be: +- Internal flag (``flg_int``) +- External flag from Python (``flg_axi``) +- Division completion flag (``flg_div``) +- Etc. + +4.7.5. LFSR (Random Number Generator) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The LFSR generates pseudo-random numbers accessible via `s_rand` (s1). + +**Configuration Register (AXI core_cfg, address 0x07):** + +.. list-table:: + :header-rows: 1 + :widths: 20 20 60 + + * - Bits + - Value + - Mode + * - 1:0 + - 0 (``STOP``) + - LFSR stops. `s_rand` constant. + * - 1:0 + - 1 (``FREE_RUN``) + - LFSR advances every `c_clk` cycle. + * - 1:0 + - 2 (``READ_STEP``) + - LFSR advances when `s_rand` is read. + * - 1:0 + - 3 (``WRITE_STEP``) + - LFSR advances when `s_rand` is written. + +**Example Configuration (from Python):** + +.. code-block:: python + + # Configure LFSR to advance on each read (mode 2 = READ_STEP) + soc.tproc.set_lfsr_cfg(mode=2) + +**Assembly Usage:** + +.. code-block:: text + + REG_WR r0 op -op(s_rand) // reads random number (advances if mode=2) + REG_WR r1 op -op(s_rand) // next random number + +**Polynomial:** The LFSR implements Fibonacci series with polynomial +`x^31 + x^21 + x^1 + x^0` (maximum length sequence). + +4.7.6. WAIT and CLEAR Macros +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +These are not hardware peripherals but assembler macros that expand to instruction sequences. + +**WAIT time @N - Expansion:** + +.. code-block:: text + + // WAIT time @1000 expands to: + TEST -op(s_usr_time - #1000) + JUMP HERE -if(S) // loop until s_usr_time >= 1000 + +**Waiting for ARITH -- no macro, write it by hand:** + +Unlike ``time``/``div_dt``/``port_dt``, ``arith_dt`` is **not** a +recognized ``WAIT`` operand -- the assembler raises an error if you write +``WAIT arith_dt``. Write the equivalent TEST + JUMP loop directly: + +.. code-block:: text + + TEST -op(s_status AND #2) // test bit 1 (ARITH_DT_NEW) + JUMP HERE -if(Z) // loop until set + +**CLEAR arith - Expansion:** + +.. code-block:: text + + // CLEAR arith expands to: + REG_WR s_ctrl imm clr_arith // s_ctrl[16] = 1 + +4.7.7. Summary: Peripheral Control Flow Pattern +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +**Standard pattern for all peripherals:** + +.. code-block:: text + + // 1. Start (instruction only) + ARITH T r1 r2 + + // 2. Wait for completion (poll s_status -- no WAIT macro, write by hand) + TEST -op(s_status AND #2) -uf + JUMP HERE -if(Z) + + // 3. Read result (from dedicated sreg) + REG_WR r3 op -op(s_arith_low) + + // 4. Clear new-data flag + CLEAR arith + +**For peripherals that produce new data asynchronously (input ports):** + +.. code-block:: text + + // 1. Wait for data arrival (poll s_status) + WAIT port_dt + + // 2. Read data + DPORT_RD p0 + REG_WR r0 op -op(s_port_l) + + // 3. Clear flag (auto-cleared by read, or manually) + CLEAR port + +4.8. Quick Reference: Register Naming in Assembly +-------------------------------------------------- + +.. list-table:: + :header-rows: 1 + :widths: 20 30 50 + + * - Register Type + - Prefix + - Examples + * - Data registers + - ``r`` + - ``r0``, ``r1``, ... ``r31`` + * - Special functions + - ``s`` + - ``s0``, ``s_rand``, ``s_status``, ``s_out_time`` + * - Wave parameters + - ``w`` + - ``w0``, ``w_freq``, ``w_phase``, ``w_gain`` + * - Composite wave + - ``r_wave`` + - ``r_wave`` (no number) + * - Aliases (user-defined) + - any + - ``.ALIAS my_var r5`` then use ``my_var`` + +**Important:** The assembler is case‑sensitive for register names. ``R0`` is NOT the same as ``r0``. Always use lowercase ``r``, ``s``, ``w``. + +4.9. Common Mistakes with Registers +------------------------------------ + +**Mistake 1: Using r_wave when you meant a wreg** + +.. code-block:: text + + // Wrong: trying to write only frequency + REG_WR r_wave imm #0x1000000 // This would zero out other parameters! + + // Correct: write to w_freq directly + REG_WR w_freq imm #0x1000000 + +**Mistake 2: Reading s_status without masking** + +.. code-block:: text + + // Wrong: compares entire status (many bits may be set) + TEST -op(s_status - #4) // checks if status == 4 + + // Correct: mask only the bit you care about + TEST -op(s_status AND #4) // checks only bit 2 + +**Mistake 3: Using s_out_time as read‑only** + +.. code-block:: text + + // Wrong: trying to read current time + REG_WR r0 op -op(s_out_time) // this reads the OUTPUT time, not current time! + + // Correct: use s_usr_time for current time + REG_WR r0 op -op(s_usr_time) + +------------------------------------------------------------------------------- + +5. Instruction Set – Task‑Oriented Guide +======================================== + +5.1. Moving Data +---------------- + +**Register to register:** + +.. code-block:: text + + REG_WR r1 op -op(r0) // r1 = r0 + REG_WR r1 op -op(s_rand) // r1 = random number + +**Immediate to register:** + +.. code-block:: text + + REG_WR r0 imm #12345 // r0 = 12345 + REG_WR r0 imm #hDEADBEEF // r0 = 0xDEADBEEF (hex) + REG_WR r0 imm #b10101010 // r0 = 0xAA (binary) + +**Memory to register:** + +.. code-block:: text + + REG_WR r0 dmem [&100] // r0 = DMEM[100] + REG_WR r_wave wmem [&5] // r_wave = WMEM[5] + +**Register to memory:** + +.. code-block:: text + + DMEM_WR [&100] imm #42 // DMEM[100] = 42 + DMEM_WR [r0] op -op(r1) // DMEM[r0] = r1 + WMEM_WR [&5] // WMEM[5] = r_wave + +5.2. Arithmetic and Logic +------------------------- + +**Addition and subtraction:** + +.. code-block:: text + + REG_WR r2 op -op(r0 + #100) // r2 = r0 + 100 + REG_WR r2 op -op(r0 - r1) // r2 = r0 - r1 + +**Bitwise operations:** + +.. code-block:: text + + REG_WR r2 op -op(r0 AND #hFF) // r2 = r0 & 0xFF (lower byte) + REG_WR r2 op -op(r0 OR r1) // r2 = r0 | r1 + REG_WR r2 op -op(r0 XOR r1) // r2 = r0 ^ r1 + REG_WR r2 op -op(NOT r0) // r2 = ~r0 + +**Shifts:** + +.. code-block:: text + + REG_WR r2 op -op(r0 SL #2) // r2 = r0 << 2 (logical left) + REG_WR r2 op -op(r0 SR #1) // r2 = r0 >> 1 (logical right) + REG_WR r2 op -op(r0 ASR #1) // r2 = r0 >> 1 (arithmetic, sign preserved) + +**Special operations:** + +.. code-block:: text + + REG_WR r2 op -op(MSH r0) // r2 = upper 16 bits of r0 + REG_WR r2 op -op(LSH r0) // r2 = lower 16 bits of r0 + REG_WR r2 op -op(SWP r0) // r2 = swap upper and lower 16 bits + REG_WR r2 op -op(ABS r0) // r2 = |r0| (absolute value) + REG_WR r2 op -op(PAR r0) // r2 = parity of r0 (0 or 1) + +5.3. Multiplication (ARITH) +--------------------------- + +The ARITH unit uses the FPGA's DSP48 slices. It computes ``(A op D) * B [+|- C]`` +(the DSP48E2's pre-adder is on the A/D inputs, NOT on B; ``B`` is the +multiplier and ``C`` is the post-adder/subtracter). + +**Operation codes:** + +.. list-table:: + :header-rows: 1 + :widths: 18 30 52 + + * - Mnemonic + - Formula + - Example + * - ``ARITH T A B`` + - A * B + - ``ARITH T r1 r2`` = r1 * r2 + * - ``ARITH TP A B C`` + - A * B + C + - ``ARITH TP r1 r2 s_arith_l`` = r1 * r2 + s3 + * - ``ARITH TM A B C`` + - A * B - C + - ``ARITH TM r1 r2 r3`` = r1 * r2 - r3 + * - ``ARITH PT D A B`` + - (D + A) * B + - ``ARITH PT r1 r2 r3`` = (r1 + r2) * r3 + * - ``ARITH MT D A B`` + - (D - A) * B + - ``ARITH MT r1 r2 r3`` = (r1 - r2) * r3 + * - ``ARITH PTP D A B C`` + - (D + A) * B + C + - ``ARITH PTP r1 r2 r3 r4`` = (r1 + r2) * r3 + r4 + * - ``ARITH PTM D A B C`` + - (D + A) * B - C + - ``ARITH PTM r1 r2 r3 r4`` = (r1 + r2) * r3 - r4 + * - ``ARITH MTP D A B C`` + - (D - A) * B + C + - ``ARITH MTP r1 r2 r3 r4`` = (r1 - r2) * r3 + r4 + * - ``ARITH MTM D A B C`` + - (D - A) * B - C + - ``ARITH MTM r1 r2 r3 r4`` = (r1 - r2) * r3 - r4 + +.. note:: + The written argument order is **D, A, B[, C]** for the P/M variants (the + mnemonic's first operand is the pre-adder's ``D`` input, not ``A``) -- + verified against ``Instruction.ARITH()`` in ``tprocv2_assembler.py``, + which maps ``R1`` -> ``RsD``, ``R2`` -> ``RsA``, ``R3`` -> ``RsB``, and + (where present) ``R4`` -> ``RsC``. An earlier revision of this table had + A and D swapped in every worked example. + + +**Typical use: multiply‑accumulate for digital filtering** + +.. code-block:: text + + // Example: y = (r1 * r2) + r3 + REG_WR r1 imm #100 + REG_WR r2 imm #200 + REG_WR r3 imm #50 + ARITH T r1 r2 // r1 * r2 takes 2 cycles + TEST -op(s_status AND #2) -uf // no WAIT macro for arith_dt -- poll by hand + JUMP HERE -if(Z) + REG_WR r4 op -op(s_arith_low) // r4 = 20000 (product) + REG_WR r4 op -op(r4 + r3) // r4 = 20000 + 50 = 20050 + +**Better real example: (A * B) + C with ARITH** + +The ARITH unit can compute (D ± A) * B ± C. To get A * B + C, set D=0, use addition for the first term, and addition for the last term. You need a register that contains 0 (use s_zero). + +.. code-block:: text + + // (0 + r1) * r2 + r3 + ARITH PTP r1 r2 s_zero r3 + TEST -op(s_status AND #2) -uf // no WAIT macro for arith_dt -- poll by hand + JUMP HERE -if(Z) + REG_WR r4 op -op(s_arith_low) + + +5.3.1 ARITH Command Decoder: Understanding PTP, MTM, T, etc. + +The ARITH instruction uses a compact 2-3 letter code that encodes the entire formula. + +**Formula Pattern:** (D ± A) * B ± C + +Where: +- **A, B, C, D** are registers (rX, sY, or wZ) +- **D** is often s_zero (0) if not used + +**Decoding the mnemonic:** + +The mnemonic consists of up to 3 letters. Read them from LEFT to RIGHT: + +.. list-table:: ARITH Mnemonic Decoder + :header-rows: 1 + :widths: 15 25 50 + + * - Mnemonic + - Number of operands + - Formula + * - T + - 2 + - A * B + * - PT + - 3 + - (A + B) * C + * - MT + - 3 + - (A - B) * C + * - PTP + - 4 + - (A + B) * C + D + * - PTM + - 4 + - (A + B) * C - D + * - MTP + - 4 + - (A - B) * C + D + * - MTM + - 4 + - (A - B) * C - D + +**Memory trick to remember:** + +.. code-block:: text + + T = Times (multiply only) + P = Plus (addition in first part) + M = Minus (subtraction in first part) + TP = Times Plus (multiply then add) + TM = Times Minus (multiply then subtract) + + Read PT as "Plus then Times" → (A+B)*C + Read PTP as "Plus then Times then Plus" → (A+B)*C + D + +**Examples decoded:** + +.. code-block:: text + + ARITH T r1 r2 → r1 × r2 + ARITH PT r1 r2 r3 → (r1 + r2) × r3 + ARITH MT r1 r2 r3 → (r1 - r2) × r3 + ARITH PTP r1 r2 r3 r4 → (r1 + r2) × r3 + r4 + ARITH PTM r1 r2 r3 r4 → (r1 + r2) × r3 - r4 + ARITH MTP r1 r2 r3 r4 → (r1 - r2) × r3 + r4 + ARITH MTM r1 r2 r3 r4 → (r1 - r2) × r3 - r4 + +**Quick Reference Card for ARITH:** + +.. code-block:: text + + ┌─────────────────────────────────────────────────────────────────┐ + │ USE THIS CHEAT SHEET FOR ARITH │ + ├─────────────────────────────────────────────────────────────────┤ + │ │ + │ Need: A * B → ARITH T rA rB │ + │ Need: (A + B) * C → ARITH PT rA rB rC │ + │ Need: (A - B) * C → ARITH MT rA rB rC │ + │ Need: (A + B) * C + D → ARITH PTP rA rB rC rD │ + │ Need: (A + B) * C - D → ARITH PTM rA rB rC rD │ + │ Need: (A - B) * C + D → ARITH MTP rA rB rC rD │ + │ Need: (A - B) * C - D → ARITH MTM rA rB rC rD │ + │ │ + └─────────────────────────────────────────────────────────────────┘ + +**Complete Working Example:** + +.. code-block:: text + + // Calculate: (r1 + r2) * r3 + r4 + REG_WR r1 imm #10 + REG_WR r2 imm #20 + REG_WR r3 imm #3 + REG_WR r4 imm #5 + + ARITH PTP r1 r2 r3 r4 + TEST -op(s_status AND #2) -uf // no WAIT macro for arith_dt -- poll by hand + JUMP HERE -if(Z) + REG_WR r5 op -op(s_arith_low) // r5 = (10+20)*3+5 = 95 + +5.4. Division (DIV) +-------------------- + +The DIV block performs **unsigned** 32‑bit integer division in 32 cycles. + +**Syntax:** + +.. code-block:: text + + DIV numerator denominator + +- numerator: a register (rX, sY, or wZ) +- denominator: a register OR a 24‑bit immediate (#value) + +**Example: divide r1 by r2, get quotient and remainder** + +.. code-block:: text + + DIV r1 r2 // start division + WAIT div_dt // wait 32 cycles (macro) + REG_WR r3 op -op(s_div_q) // r3 = quotient + REG_WR r4 op -op(s_div_r) // r4 = remainder + +**Important:** Division is unsigned only. For signed division, convert to positive, divide, then adjust sign. + +5.5. Flow Control +----------------- + +**Unconditional jump:** + +.. code-block:: text + + JUMP LABEL // always jump + +**Conditional jump (most common for loops):** + +.. code-block:: text + + JUMP LABEL -if(NZ) // jump if last ALU result was not zero + +**Conditional jump with decrement (standard loop pattern):** + +.. code-block:: text + + REG_WR r0 imm #10 // r0 = 10 (loop counter) + LOOP: + // ... do something ... + JUMP LOOP -wr(r0 op) -op(r0 - #1) -uf // decrement r0, update flags, jump if not zero + +**Avoiding the branch penalty:** + +Because branches cause a 2‑cycle pipeline flush, use conditional execution for simple cases: + +.. code-block:: text + + // Instead of: + // JUMP SKIP -if(Z) + // REG_WR r1 imm #1 + // SKIP: + + // Do: + REG_WR r1 imm #1 -if(NZ) // only executed if Z flag is NOT set + +5.6. Memory Addressing Modes - Detailed Reference +------------------------------------------------- + +The tProcessor supports multiple addressing modes for different memory types. +Understanding these modes is crucial for writing efficient code. + +5.6.1. DMEM Addressing Modes +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Data Memory (DMEM) supports 4 addressing modes. The address is computed as +``rsA0 + rsA1`` in the RTL (``qcore_cpu.sv``), where each source can be an +11-bit literal or a 6-bit register specifier. The ``DF`` field controls the +immediate size when literals are used. + +.. list-table:: DMEM Addressing Modes + :header-rows: 1 + :widths: 20 20 20 40 + + * - Mode + - Syntax + - AI + - Example + * - Literal + - ``[&imm]`` + - 1 + - ``DMEM_WR [&10] imm #42`` + * - Register + - ``[rX]`` + - 0 + - ``DMEM_WR [r1] imm #42`` + * - Indexed Literal + - ``[rX + &imm]`` + - 1 + - ``DMEM_WR [r1+&4] imm #42`` + * - Indexed Register + - ``[rX + rY]`` + - 0 + - ``DMEM_WR [r2+r3] imm #42`` + +**When to use each mode:** + +- **Literal**: Fixed addresses (constants, lookup tables) +- **Register**: Dynamic addressing (arrays with variable index) +- **Indexed Literal**: Arrays with base pointer + small offset +- **Indexed Register**: 2D arrays or complex data structures + +**Example: Array traversal with indexed literal** + +.. code-block:: text + + REG_WR r0 imm #0 ; index + REG_WR r1 imm #10 ; base address + LOOP: + REG_WR r2 dmem [r1 + r0] ; read array[r0] from base r1 + ; ... process r2 ... + REG_WR r0 op -op(r0 + #1) -uf + JUMP LOOP -if(NZ) + +5.6.2. WMEM Addressing Modes +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Wave Memory (WMEM) supports 2 addressing modes. The address is taken from +``rsA0`` only (``qcore_cpu.sv``: ``x1_wave_addr = x1_rs_a0_dt[WMEM_AW-1:0]``). + +.. list-table:: WMEM Addressing Modes + :header-rows: 1 + :widths: 20 20 20 40 + + * - Mode + - Syntax + - AI + - Example + * - Literal + - ``[&imm]`` + - 1 + - ``WMEM_WR [&5]`` + * - Register + - ``[rX]`` + - 0 + - ``WMEM_WR [r0]`` + +**Example: Sequentially loading waveforms** + +.. code-block:: text + + REG_WR r0 imm #0 + LOOP: + REG_WR r_wave wmem [r0] ; load waveform from WMEM[r0] + WPORT_WR p1 r_wave @s_out_time + REG_WR r0 op -op(r0 + #1) -uf + JUMP LOOP -if(NZ) + + +5.6.3. PMEM Addressing (Branch Instructions) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Program Memory (PMEM) addressing is used only for JUMP, CALL, and RET: + +.. list-table:: PMEM Addressing Modes + :header-rows: 1 + :widths: 20 20 20 40 + + * - Mode + - Syntax + - Encoding (AI bits) + - Example + * - Immediate (Label) + - ``LABEL`` + - 001 + - ``JUMP LOOP`` + * - Register (s_addr) + - ``s_addr`` + - 010 + - ``JUMP s_addr`` + * - Special constants + - ``HERE``, ``PREV``, ``NEXT``, ``SKIP`` + - (assembler) + - ``JUMP HERE -if(Z)`` + +5.7. Dual Task Instructions - Unified Reference +----------------------------------------------- + +One of the most powerful features of the tProcessor is the ability to execute +**two operations in a single 72-bit instruction word**. The 16-bit code field +encodes the secondary tasks in dedicated bits: + +- ``bit 3`` (``-wr`` / **SDT**): dual register write enable. +- ``bit 7`` (``-wp`` / **SPT**): dual port write enable. +- ``bit 9`` (``-ww`` / **SWT**): dual wave-memory write enable. + +The dual-task enable bits are only honoured on instruction categories that +support them (see matrix below); otherwise the bit is reserved. The RTL +enforces this via the ``cfg_dual_*_en`` gating terms in +``qcore_cpu.sv``. + +5.7.1. Types of Dual Tasks +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: Dual Task Types + :header-rows: 1 + :widths: 15 15 15 55 + + * - Type + - Assembler flag + - Code bit + - Description + * - Second Data Task + - ``-wr(dest, source)`` + - ``code[3]`` (SDT) + - Writes a register in the same instruction + * - Second Wave Task + - ``-ww [&addr]`` + - ``code[9]`` (SWT) + - Also writes the r_wave contents into WMEM at ``&addr`` (used with WPORT_WR) + * - Second Port Task + - ``-wp(port, source)`` + - ``code[7]`` (SPT) + - Also drives a wave port with r_wave / WMEM data (used with REG_WR) + +5.7.2. Rules for Dual Tasks +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +1. **Only ONE immediate value** per instruction total (the ``DF`` field is shared). +2. **The source for SDT** can be an ALU operation (``-op``) or an immediate (``imm``). +3. **The destination for SDT** can be any register (r, s, or r_wave). +4. **SPT (``-wp``)** is allowed with REG_WR (writes wave data to a port); **SWT (``-ww``)** is allowed with WPORT_WR (writes r_wave into WMEM at the same time the wave is played). +5. The ``COND`` field applies to the whole instruction (the primary task AND any active dual tasks); the dual tasks don't get their own condition. + +5.7.3. Instruction Support Matrix +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: Dual Task Support by Instruction + :header-rows: 1 + :widths: 22 15 15 15 35 + + * - Instruction + - SDT (-wr) + - SWT (-ww) + - SPT (-wp) + - Notes + * - REG_WR (SRC=op/imm/dmem/label) + - ✅ + - ❌ + - ❌ + - SDT only on ``-op`` source + * - REG_WR (SRC=wmem) + - ✅ + - ❌ + - ✅ (-wp sets SO=1) + - Loads r_wave from WMEM and writes to a port + * - DMEM_WR + - ✅ + - ❌ + - ❌ + - + * - WMEM_WR + - ✅ + - ✅ (primary, ``-ww`` is what WMEM_WR *is*) + - ✅ + - Can also output the waveform to a port at the same time + * - DPORT_WR + - ✅ + - ❌ + - ❌ + - + * - TRIG + - ✅ + - ❌ + - ❌ + - + * - WPORT_WR (SRC=wmem) + - ✅ + - ❌ + - ✅ (primary) + - + * - WPORT_WR (SRC=r_wave) + - ✅ + - ✅ + - ✅ (primary) + - All three dual tasks available + * - JUMP/CALL/RET + - ✅ + - ❌ + - ❌ + - SDT executes before branch resolves + * - TEST (CFG header=000) + - ❌ + - ❌ + - ❌ + - No destination + +5.7.4. Practical Examples +^^^^^^^^^^^^^^^^^^^^^^^^^ + +**Example 1: Increment counter while writing data** + +.. code-block:: text + + ; Without SDT (2 instructions, 2 cycles) + DPORT_WR p0 reg r5 @1000 + REG_WR r5 op -op(r5 + #1) + + ; With SDT (1 instruction, 1 cycle) + DPORT_WR p0 reg r5 @1000 -wr(r5 op) -op(r5 + #1) + +**Example 2: Loop with decrement and branch** + +.. code-block:: text + + REG_WR r0 imm #10 + LOOP: + ; ... loop body ... + JUMP LOOP -wr(r0 op) -op(r0 - #1) -uf -if(NZ) + ; Decrement, update flags, and branch in one cycle + +**Example 3: Load waveform into r_wave and play it on a port** + +.. code-block:: text + + REG_WR r_wave wmem [&5] -wp(p0, wmem) @1000 + ; Load waveform from WMEM[r0] and increment r0 + + +5.8. Peripherals Control Instructions - Bit Field Reference +----------------------------------------------------------- + +Instructions with `HEADER = 010` (binary) control the **internal** peripheral +blocks (TIME, FLAG, ARITH, DIV). Instructions with `HEADER = 011` control +the **external** peripheral blocks (NET, COM, PA, PB). The peripheral select +is encoded in the 3-bit ``CTRL_ADDR`` field (see tables below). The 4-bit +``OPERATION`` (or 5-bit for external peripherals) selects the sub-function. + +.. note:: + The instruction width is **72 bits**. Tables show bit positions from MSB (bit 71) to LSB (bit 0). + +5.8.1. TIME Instruction (Header=010, CTRL_ADDR=000) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The TIME instruction controls the absolute time counter and reference time. + +**Bit Encoding:** + +.. list-table:: TIME Instruction (72-bit encoding) + :header-rows: 2 + :widths: 10 8 5 5 5 5 8 10 5 5 5 5 5 5 5 + + * - Bit(s) + - 71:69 + - 68 + - 67 + - 66 + - 65:63 + - 62:60 + - 59:55 + - 54:45 + - 44:39 + - 38:31 + - 30:23 + - 22:15 + - 14:7 + - 6:0 + * - **Field** + - HEADER + - AI + - DF_H + - DF_L + - COND + - CTRL_ADDR + - OPERATION + - (rsA0) + - (rsA1) + - (rd0) + - (rd1) + - (imm) + - (imm) + - RD + * - **Value** + - 010 + - a + - d + - f + - cond + - 000 + - see table + - 0 / reg addr + - 0 / reg addr + - 0 / reg addr + - 0 / reg addr + - imm[31:24] + - imm[23:16] + - dest + +.. list-table:: TIME_OP Field Values (assembler: ``C_OP``) + :header-rows: 1 + :widths: 15 20 65 + + * - OPERATION bits + - Mnemonic + - Effect + * - ``_0001`` + - ``rst`` + - ``t_abs = 0``, ``t_ref = 0``, core reset (source data ignored) + * - ``_0010`` + - ``updt`` + - ``t_abs = t_abs + Source Data`` (immediate or register) + * - ``_0100`` + - ``set_ref`` + - ``t_ref = Source Data`` (t_abs unchanged) + * - ``_1000`` + - ``inc_ref`` + - ``t_ref = t_ref + Source Data`` + +**Field Descriptions:** + +.. list-table:: + :header-rows: 1 + :widths: 15 15 70 + + * - Field + - Bits + - Description + * - HEADER + - 71:69 + - Always 111 for peripheral instructions + * - AI (Address Immediate) + - 68:66 + - 0=Source is register, 1=Source is immediate value + * - DF (Data Format) + - 65:64 + - Source data format (00=32-bit immediate, 01=24-bit, etc.) + * - OPCODE + - 63:61 + - Always 010 for TIME instruction + * - TIME_OP + - 60:58 + - Operation code (see table above) + * - Source Data + - 57:0 + - Time value (immediate) or register address (if AI=0) + +**Assembly Syntax:** + +.. code-block:: text + + TIME rst // Reset absolute time + TIME set_ref r2 // Set reference time to value in r2 + TIME updt #15750 // Add 15750 to absolute time + TIME inc_ref #15750 // Add 15750 to reference time + +5.8.2. FLAG Instruction (Header=111) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The FLAG instruction modifies the internal flag bit. + +**Bit Encoding:** + +.. list-table:: ARITH Instruction (72-bit encoding) + :header-rows: 2 + :widths: 10 10 10 10 10 10 10 10 10 + + * - Row Type + - 71:69 + - 68:66 + - 65:64 + - 63:53 + - 52:42 + - 41:31 + - 30:20 + - 19:0 + * - **Field** + - HEADER + - AI/DF + - OPCODE + - OPERAND_A + - OPERAND_B + - OPERAND_C + - OPERAND_D + - (unused) + * - **Value** + - 111 + - varies + - see table + - reg addr + - reg addr + - reg addr + - reg addr + - 0 + +.. list-table:: FLAG_OP Field Values + :header-rows: 1 + :widths: 15 20 60 + + * - FLAG_OP (bits 60:59) + - Mnemonic + - Effect + * - 00 + - ``set`` + - Internal flag = 1 + * - 01 + - ``clr`` + - Internal flag = 0 + * - 10 + - ``inv`` + - Internal flag = ~internal flag + * - 11 + - (reserved) + - Reserved for future use + +**Assembly Syntax:** + +.. code-block:: text + + FLAG set // Set internal flag + FLAG clr // Clear internal flag + FLAG inv // Invert internal flag + +5.8.3. ARITH Instruction (Header=111) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ARITH instruction starts a multiply-accumulate operation on the DSP. + +**Bit Encoding:** + +.. list-table:: ARITH Instruction (72-bit encoding) + :header-rows: 2 + :widths: 10 10 10 10 10 10 10 10 20 + + * - Row Type + - 71:69 + - 68:66 + - 65:64 + - 63:61 + - 60:50 + - 49:39 + - 38:28 + - 27:0 + * - **Field** + - HEADER + - AI/DF + - OPCODE + - OPERAND_A + - OPERAND_B + - OPERAND_C + - OPERAND_D + - (unused) + * - **Value** + - 111 + - varies + - see table + - reg addr + - reg addr + - reg addr + - reg addr + - 0 + +.. list-table:: ARITH OPCODE Values (bits 63:61) + :header-rows: 1 + :widths: 15 15 20 45 + + * - OPCODE + - Mnemonic + - Operands + - Formula + * - 000 + - T + - 2 + - A * B + * - 001 + - PT + - 3 + - (A + B) * C + * - 010 + - MT + - 3 + - (A - B) * C + * - 011 + - PTP + - 4 + - (A + B) * C + D + * - 100 + - PTM + - 4 + - (A + B) * C - D + * - 101 + - MTP + - 4 + - (A - B) * C + D + * - 110 + - MTM + - 4 + - (A - B) * C - D + +**Register Addressing:** Each operand field (60:50, 49:39, etc.) contains a 11-bit register address: +- Bits 10:8 = Register bank (000=r, 001=s, 010=w) +- Bits 7:0 = Register index (0-31) + +**Assembly Syntax:** + +.. code-block:: text + + ARITH T r1 r2 // r1 * r2 + ARITH PT r1 r2 r3 // (r1 + r2) * r3 + ARITH PTP r1 r2 r3 r4 // (r1 + r2) * r3 + r4 + +5.8.4. DIV Instruction (Header=111) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The DIV instruction starts unsigned 32-bit integer division. + +**Bit Encoding:** + +.. list-table:: DIV Instruction (72-bit encoding) + :header-rows: 2 + :widths: 10 10 5 5 5 5 8 10 10 10 20 + + * - Bit(s) + - 71:69 + - 68 + - 67 + - 66 + - 65 + - 64 + - 63:53 + - 52:42 + - 41:31 + - 30:0 + * - **Field** + - HEADER + - AI_H + - AI_L + - DF_H + - DF_L + - OPCODE + - NUMERATOR + - DENOMINATOR + - (unused) + - (unused) + * - **Value** + - 111 + - a + - i + - d + - f + - 001 + - reg addr + - reg addr + - 0 + - 0 + +**Field Descriptions:** + +- **AI bit (68:66)**: 0 = Denominator is register, 1 = Denominator is immediate (24-bit) +- **Numerator (60:50)**: Always a register address +- **Denominator (49:39)**: Register address or 24-bit immediate value + +**Assembly Syntax:** + +.. code-block:: text + + DIV r1 r2 // r1 / r2 (both registers) + DIV r1 #100 // r1 / 100 (immediate denominator) + +5.8.5. NET Instruction (Header=111) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The NET instruction communicates with the QICK network interface. + +**Bit Encoding:** + +.. list-table:: NET Instruction (72-bit encoding) + :header-rows: 2 + :widths: 15 10 10 15 15 35 + + * - Bit(s) + - 71:69 + - 68:66 + - 65:64 + - 63:61 + - 60:0 + * - **Field** + - HEADER + - AI/DF + - OPCODE + - NET_CMD + - DATA + * - **Value** + - 111 + - varies + - 100 + - see table + - varies + +.. list-table:: NET_CMD Field Values (bits 60:56) + :header-rows: 1 + :widths: 15 20 45 + + * - NET_CMD + - Mnemonic + - Description + * - 00000 + - ``get_net`` + - Count nodes in network + * - 00001 + - ``set_net`` + - Configure network nodes + * - 00010 + - ``sync_net`` + - Synchronize all nodes + * - 00011 + - ``get_st`` + - Read data from network node + +5.8.6. PA/PB Instructions (Header=111) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +PA and PB control custom peripherals. + +**Bit Encoding:** + +.. list-table:: PA/PB Instruction (72-bit encoding) + :header-rows: 2 + :widths: 10 10 10 10 10 10 10 10 10 10 10 + + * - Bit(s) + - 71:69 + - 68:66 + - 65:64 + - 63:61 + - 60:56 + - 55:44 + - 43:32 + - 31:20 + - 19:8 + - 7:0 + * - **Field** + - HEADER + - AI/DF + - OPCODE + - PERIPH_OP + - DATA_A + - DATA_B + - DATA_C + - DATA_D + - (unused) + - (unused) + * - **Value** + - 111 + - varies + - 101/110 + - varies + - reg/imm + - reg/imm + - reg/imm + - reg/imm + - 0 + - 0 + +**OPCODE Values:** + +- 101 = PA (Custom Peripheral A) +- 110 = PB (Custom Peripheral B) + +**Data Fields:** Each can be a register address or immediate value, depending on DF bits. + +5.8.7. Summary: Peripheral OPCODE Map +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: Complete Peripheral OPCODE Reference + :header-rows: 1 + :widths: 15 20 20 45 + + * - OPCODE (bits 63:61) + - Instruction + - Operands + - Description + * - 000 + - ARITH + - 2-4 + - Multiply-accumulate (2 cycles) + * - 001 + - DIV + - 2 + - Unsigned integer division (32 cycles) + * - 010 + - TIME + - 0-1 + - Time counter control + * - 011 + - FLAG + - 0 + - Internal flag control + * - 100 + - NET + - 0-1 + - Network communication + * - 101 + - PA + - 4 + - Custom peripheral A + * - 110 + - PB + - 4 + - Custom peripheral B + * - 111 + - (reserved) + - + - Reserved for future use + +5.8.8. Programming Pattern +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +**Standard pattern for peripheral control:** + +.. code-block:: text + + // 1. Configure data source (if reading result) + REG_WR s_cfg imm src_arith // route ARITH result to s_core_r1 + + // 2. Clear any old flags + CLEAR arith + + // 3. Start peripheral operation + ARITH PTP r1 r2 r3 r4 + + // 4. Wait for completion (no WAIT macro for arith_dt -- poll by hand) + TEST -op(s_status AND #2) -uf + JUMP HERE -if(Z) + + // 5. Read result + REG_WR r0 op -op(s_arith_low) + + // 6. Clear flag for next use + CLEAR arith + +Related Status Bits (s_status): + +.. list-table:: Peripheral Status Bits + :header-rows: 1 + :widths: 20 20 20 25 + + * - Peripheral + - Ready Bit (RDY) + - New Data Bit (DT_NEW) + - Clear Method + * - ARITH + - bit 0 + - bit 1 + - CLEAR arith or read + * - DIV + - bit 2 + - bit 3 + - CLEAR div or read + * - QPA (Custom A) + - bit 8 + - bit 9 + - CLEAR qpa + * - QPB (Custom B) + - bit 10 + - bit 11 + - CLEAR qpb + * - Input Ports + - (none) + - bits 31:16 + - CLEAR port or read + +5.9. Subroutines (CALL/RET) +--------------------------- + +The tProc supports nested calls up to 256 levels deep. + +.. code-block:: text + + CALL MY_SUBROUTINE + // ... after subroutine returns, execution continues here + + MY_SUBROUTINE: + // ... do something ... + RET + +**Important:** The stack only stores return addresses, not local variables. Use registers or DMEM for local storage. + +5.10. Waiting (WAIT macro) - Detailed Reference +----------------------------------------------- + +The ``WAIT`` instruction is an **assembler macro** that expands to a small polling loop. +It is not a single hardware instruction but a convenient way to wait for conditions. + +5.10.1. WAIT Macro Expansion +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +**WAIT time @N - Expansion:** + +.. code-block:: text + + ; Original: WAIT time @1000 + ; Expands to: + TEST -op(s_usr_time - #1000) ; Compare current time with N + JUMP HERE -if(S) ; Loop if current_time < N + +**Bit encoding of expanded instructions:** + +.. list-table:: WAIT time @N Expansion Encoding + :header-rows: 1 + :widths: 45 35 60 + + * - Instruction + - Opcode + - Description + * - ``TEST -op(s_usr_time - #N)`` + - TEST (Header=000) + - Performs subtraction, updates flags. N is 32-bit immediate. + * - ``JUMP HERE -if(S)`` + - JUMP (Header=001) + - Conditional jump to current address if Negative flag is set. + +5.10.2. WAIT div_dt - Expansion +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: text + + ; Original: WAIT div_dt + ; Expands to: + TEST -op(s_status AND #8) ; Test DIV_DT_NEW bit (bit 3) + JUMP HERE -if(Z) ; Loop while bit is 0 (Z flag set) + +**Bit encoding:** + +.. list-table:: WAIT div_dt Expansion Encoding + :header-rows: 1 + :widths: 35 30 50 + + * - Instruction + - Opcode + - Description + * - ``TEST -op(s_status AND #8)`` + - TEST (Header=000) + - AND operation with mask 0x8, updates Z flag + * - ``JUMP HERE -if(Z)`` + - JUMP (Header=001) + - Conditional jump to current address if Z flag is set (bit not set) + +.. _wait-arith-dt-manual: + +5.10.3. Waiting for ARITH -- No Macro, Write It By Hand +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Unlike ``WAIT time``/``WAIT div_dt``/``WAIT port_dt`` (real assembler +macros, confirmed against ``Instruction.WAIT()`` in +``tprocv2_assembler.py``), **``WAIT arith_dt`` is not a recognized +operand** -- the assembler raises ``RuntimeError: No Recognized +Operation`` on it. Write the equivalent TEST + JUMP loop directly instead: + +.. code-block:: text + + TEST -op(s_status AND #2) ; Test ARITH_DT_NEW bit (bit 1) + JUMP HERE -if(Z) ; Loop while bit is 0 + +5.10.4. WAIT port_dt - Expansion +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: text + + ; Original: WAIT port_dt + ; Expands to: + TEST -op(s_status AND #0xFFFF0000) ; Test any PORT_DT_NEW bit + JUMP HERE -if(Z) ; Loop if no new data on any port + +5.10.5. Custom WAIT Macro (user-defined) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can create your own wait loops for any condition: + +.. code-block:: text + + ; Wait for QPA_RDY (bit 8 of s_status) + WAIT_QPA_RDY: + TEST -op(s_status AND #0x100) ; Test bit 8 + JUMP WAIT_QPA_RDY -if(Z) ; Loop if not ready + + ; Wait for a specific input port (e.g., port 2, bit 18) + WAIT_PORT2: + TEST -op(s_status AND #1<<18) ; Test bit 18 + JUMP WAIT_PORT2 -if(Z) + +5.11. Clearing Flags (CLEAR) - Detailed Reference +------------------------------------------------- + +The ``CLEAR`` instruction is an **assembler macro** that writes a one-shot value +to the ``s_ctrl`` byte (upper 8 bits of s2) to clear ``_NEW`` flags in +``s_status``. The bit self-clears the cycle after it is written. + +5.11.1. CLEAR Macro Expansion +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +**CLEAR arith - Expansion:** + +.. code-block:: text + + ; Original: CLEAR arith + ; Expands to: + REG_WR s_ctrl imm clr_arith ; s_ctrl byte bit 0 = 1 + +**Bit encoding of expanded instruction:** + +.. list-table:: CLEAR arith Expansion Encoding + :header-rows: 1 + :widths: 20 20 60 + + * - Instruction + - Opcode + - Description + * - ``REG_WR s_ctrl imm clr_arith`` + - REG_WR (Header=100) + - Writes immediate value to s_ctrl, setting bit 0 to 1 (one-shot) + +5.11.2. CLEAR Options and Corresponding s_ctrl Bits +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: CLEAR Options + :header-rows: 1 + :widths: 20 20 15 45 + + * - CLEAR Option + - s_ctrl Bit (in byte) + - 32-bit Value + - Clears + * - ``CLEAR arith`` + - 0 + - 0x00010000 + - ``ARITH_DT_NEW`` (s_status[1]) + * - ``CLEAR div`` + - 1 + - 0x00020000 + - ``DIV_DT_NEW`` (s_status[3]) + * - ``CLEAR qnet`` + - 2 + - 0x00040000 + - ``QNET_DT_NEW`` (s_status[5]) + * - ``CLEAR qcom`` + - 3 + - 0x00080000 + - ``QCOM_DT_NEW`` (s_status[7]) + * - ``CLEAR qpa`` + - 4 + - 0x00100000 + - ``QPA_DT_NEW`` (s_status[9]) + * - ``CLEAR qpb`` + - 5 + - 0x00200000 + - ``QPB_DT_NEW`` (s_status[11]) + * - ``CLEAR port`` + - 6 + - 0x00400000 + - All ``PORT_DT_NEW`` bits (s_status[31:16]) + +5.11.3. CLEAR Macro Expansion Example +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: text + + ; Original: CLEAR div + ; Expands to: + REG_WR s_ctrl imm #0x00020000 ; Set bit 1 of s_ctrl byte (one-shot) + + ; Note: Writing to s_ctrl is self-clearing. + ; The bit returns to 0 after one clock cycle. + +5.11.4. Direct s_ctrl Usage (without CLEAR macro) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can write directly to ``s_ctrl`` to clear specific flags: + +.. code-block:: text + + ; Clear multiple flags at once + REG_WR s_ctrl imm #0x00700000 ; Clear arith + div + qpa (bits 16,17,20) + + ; Clear using predefined constants (if defined in assembler) + REG_WR s_ctrl imm clr_arith | clr_div + +5.12. Port Instructions - Bit Field Reference +--------------------------------------------- + +Instructions with `HEADER = 110` (binary) control output ports (DPORT, TRIG, WPORT) +and input ports (DPORT_RD). + +.. note:: + The detailed 72-bit tables in this section describe field semantics but + **must be verified against the authoritative sources**: + ``qick_lib/qick/tprocv2_assembler.py`` (``Instruction.PORT_WR``) and + ``firmware/rtl_lib/processors/qcore_cpu.sv``. The RTL decodes port + instructions as ``110_AI_DF__COND__CFG___ADDR____DATA__RD`` where CFG + contains SO/TO/UF/Wr/Rdi/alu_op, ADDR carries the port number or wave + address, and DATA carries the immediate or register source. + +5.12.1. DPORT_WR (Data Port Write) - Header=110 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The DPORT_WR instruction writes 32-bit data to a digital output port at a specified time. + +**Bit Encoding:** + +.. list-table:: Instruction Encoding (72-bit) + :header-rows: 2 + :widths: 10 5 5 5 5 5 5 5 5 5 5 5 5 5 5 20 + + * - Bit(s) + - 71:69 + - 68 + - 67 + - 66 + - 65 + - 64 + - 63 + - 62 + - 61 + - 60 + - 59 + - 58 + - 57 + - 56 + - 55:0 + * - **Field** + - HEADER + - AI_H + - AI_L + - DF_H + - DF_L + - (un) + - (un) + - (un) + - (un) + - (un) + - (un) + - (un) + - (un) + - (un) + - DATA + * - **Value** + - 110 + - 1 + - 1 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - varies + +**Field Descriptions:** + +.. list-table:: DPORT_WR Fields + :header-rows: 1 + :widths: 15 15 70 + + * - Field + - Bits + - Description + * - HEADER + - 71:69 + - Always 110 for port instructions + * - AI (Address Immediate) + - 68:66 + - 111 = Data is immediate, 000 = Data is from register + * - DF (Data Format) + - 65:64 + - Source data format (00=32-bit immediate, 01=24-bit, etc.) + * - PORT + - 63:61 + - Port number (0-7 for DPORT) + * - TIME_SRC + - 60:59 + - 00 = Time from s_out_time, 01 = Immediate time (@value) + * - DATA_SRC + - 58:55 + - Source of data (varies by AI/DF) + * - Imm_Data/Reg_Addr + - 54:0 + - Immediate data value or register address + +**Time Encoding:** + +.. list-table:: + :header-rows: 1 + :widths: 20 20 60 + + * - TIME_SRC bits (60:59) + - Meaning + - Example + * - 00 + - Use s_out_time register + - ``DPORT_WR p0 reg r0 @s_out_time`` + * - 01 + - Use immediate time value + - ``DPORT_WR p0 imm 1 @1000`` + +**Assembly Syntax:** + +.. code-block:: text + + DPORT_WR p0 imm 1 @1000 ; Write 1 to port 0 at time 1000 + DPORT_WR p2 reg r5 @s_out_time ; Write r5 to port 2 using s_out_time + +5.12.2. TRIG (Trigger Port Write) - Header=110 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The TRIG instruction writes a single bit (0 or 1) to a trigger output port. + +**Bit Encoding:** + +.. list-table:: TRIG Instruction (72-bit encoding) + :header-rows: 2 + :widths: 10 10 5 5 5 5 10 10 10 10 20 + + * - Bit(s) + - 71:69 + - 68 + - 67 + - 66 + - 65 + - 64 + - 63:61 + - 60 + - 59 + - 58:0 + * - **Field** + - HEADER + - AI_H + - AI_L + - DF_H + - DF_L + - (unused) + - PORT + - SET_CLR + - TIME_SRC + - (unused) + * - **Value** + - 110 + - 1 + - 1 + - 0 + - 0 + - 0 + - port # + - 0 or 1 + - 0 or 1 + - 0 + +**Field Descriptions:** + +.. list-table:: TRIG Fields + :header-rows: 1 + :widths: 15 15 70 + + * - Field + - Bits + - Description + * - HEADER + - 71:69 + - Always 110 for port instructions + * - PORT + - 63:61 + - Port number (0-31 for TRIG ports) + * - SET_CLR + - 60 + - 0 = Clear (write 0), 1 = Set (write 1) + * - TIME_SRC + - 59:58 + - 00 = Time from s_out_time, 01 = Immediate time (@value) + * - Imm_Time + - 57:0 + - Immediate time value (if TIME_SRC=01) + +**Assembly Syntax:** + +.. code-block:: text + + TRIG p0 set @150 ; Set trigger port 0 high at time 150 + TRIG p1 clr @200 ; Set trigger port 1 low at time 200 + TRIG p2 set @s_out_time ; Use s_out_time register + +5.12.3. WPORT_WR (Wave Port Write) - Header=110 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The WPORT_WR instruction writes 168-bit waveform parameters to an analog wave output port. + +**Bit Encoding:** + +.. list-table:: WPORT_WR Instruction (72-bit encoding) + :header-rows: 2 + :widths: 8 7 4 4 4 4 4 6 4 4 7 10 10 24 + + * - Bit(s) + - 71:69 + - 68 + - 67 + - 66 + - 65 + - 64 + - 63:61 + - 60 + - 59 + - 58:55 + - 54:45 + - 44:39 + - 38:0 + * - **Field** + - HEADER + - AI_H + - AI_L + - DF_H + - DF_L + - WW + - PORT + - WP + - TI + - SRC + - ADDR_SRC + - DATA_SRC + - (unused) + * - **Value** + - 110 + - 1 + - 1 + - 0 + - 0 + - 0 or 1 + - port # + - 0 or 1 + - 0 or 1 + - varies + - varies + - varies + - 0 + +**Field Descriptions:** + +.. list-table:: WPORT_WR Fields + :header-rows: 1 + :widths: 15 15 70 + + * - Field + - Bits + - Description + * - HEADER + - 71:69 + - Always 110 for port instructions + * - WW (Write Wave) + - 64 + - 1 = Write wave as second task (SWT), 0 = not a second task + * - PORT + - 63:61 + - Wave port number (0-15) + * - WP (Write Port) + - 60 + - 1 = This is a second port task (SPT), 0 = primary task + * - TI (Time Immediate) + - 59 + - 0 = Use s_out_time, 1 = Use immediate time @value + * - SRC (Source Select) + - 58:55 + - 0000 = Source is r_wave, 0001 = Source is WMEM + * - ADDR_SRC + - 54:45 + - WMEM address (immediate or register, depending on AI/DF) + * - DATA_SRC + - 44:39 + - Source register for r_wave (if SRC=0000 and not immediate) + * - Imm_Time + - 38:0 + - Immediate time value (if TI=1) + +**Source Encoding (SRC bits 58:55):** + +.. list-table:: + :header-rows: 1 + :widths: 15 20 65 + + * - SRC + - Source + - Description + * - 0000 + - r_wave + - Use the r_wave register + * - 0001 + - wmem + - Load from WMEM address (requires ADDR_SRC) + +**Assembly Syntax:** + +.. code-block:: text + + WPORT_WR p0 r_wave @1000 ; Write r_wave to port 0 at time 1000 + WPORT_WR p1 wmem [&5] @s_out_time ; Write WMEM[5] to port 1 using s_out_time + WPORT_WR p2 r_wave ; Write r_wave at time from s_out_time + +5.12.4. DPORT_RD (Data Port Read) - Header=110 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The DPORT_RD instruction reads 64-bit data from an input port (AXI-Stream interface) +to s_port_l (s8) and s_port_h (s9). + +**Bit Encoding:** + +.. list-table:: DPORT_RD Instruction (72-bit encoding) + :header-rows: 2 + :widths: 10 10 5 5 5 5 10 10 30 + + * - Bit(s) + - 71:69 + - 68 + - 67 + - 66 + - 65 + - 64 + - 63:61 + - 60:0 + * - **Field** + - HEADER + - AI_H + - AI_L + - DF_H + - DF_L + - (unused) + - PORT + - (unused) + * - **Value** + - 110 + - 0 + - 0 + - 0 + - 0 + - 0 + - port # + - 0 + +**Field Descriptions:** + +.. list-table:: DPORT_RD Fields + :header-rows: 1 + :widths: 15 15 70 + + * - Field + - Bits + - Description + * - HEADER + - 71:69 + - Always 110 for port instructions + * - PORT + - 63:61 + - Input port number (0-3 typically, up to 16 configurable) + +**Result Registers:** + +- s8 (s_port_l): Lower 32 bits of input data +- s9 (s_port_h): Upper 32 bits of input data + +**Status Bits:** + +- s_status[31:16] (PORT_DT_NEW): Bit N indicates new data on port N +- Cleared by reading the port or by ``CLEAR port`` + +**Assembly Syntax:** + +.. code-block:: text + + DPORT_RD p0 ; Read port 0 to s_port_l/s_port_h + DPORT_RD p1 -wr(r15 op) -op(r1-#1) ; Read port 1 with dual task + +5.12.5. Summary: Port Instruction OPCODE Map +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: Port Instruction Summary + :header-rows: 1 + :widths: 20 20 20 40 + + * - Instruction + - Header + - Sub-fields + - Description + * - DPORT_WR + - 110 + - PORT, TIME_SRC, DATA_SRC + - Write 32-bit data to digital port + * - TRIG + - 110 + - PORT, SET_CLR, TIME_SRC + - Write single bit to trigger port + * - WPORT_WR + - 110 + - PORT, TI, SRC, WW, WP + - Write 168-bit waveform to analog port + * - DPORT_RD + - 110 + - PORT + - Read 64-bit from input port + +5.12.6. Dual Task Options for Port Instructions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Port instructions can include dual tasks: + +- **-wr(rd, src)** : Second Data Task - writes a register +- **-uf** : Update flags (used with -wr) +- **-wp(port)** : Second Port Task - writes a wave port (only for WPORT_WR?) + +**Example with dual task:** + +.. code-block:: text + + DPORT_WR p0 reg r5 @s_out_time -wr(r1 imm) #100 + ; Primary: Write r5 to port 0 + ; Secondary: Write 100 to r1 (same cycle) + + TRIG p0 set @s_out_time -wr(r0 op) -op(r0 + #1) + ; Primary: Set trigger + ; Secondary: Increment r0 + +**Bit encoding for dual task (SDT) in port instructions:** + +.. list-table:: Dual Task Fields in Port Instructions + :header-rows: 1 + :widths: 15 15 70 + + * - Field + - Bits + - Description + * - WR (Write Register) + - 57 + - 1 = Second Data Task present + * - UF (Update Flag) + - 56 + - 1 = Update ALU flags + * - RDI (Register Destination Immediate) + - 55 + - 0 = ALU source, 1 = Immediate source + * - ALU_OP + - 54:50 + - ALU operation code (for -op()) + +5.13. Memory Instructions - Bit Field Reference +------------------------------------------------ + +Instructions with `HEADER = 101` (binary) write to Data Memory (DMEM) or Wave Parameter Memory (WMEM). + +5.13.1. DMEM_WR (Data Memory Write) - Header=101 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The DMEM_WR instruction writes 32-bit data to Data Memory at a specified address. + +**Bit Encoding:** + +.. list-table:: DMEM_WR Instruction (72-bit encoding) + :header-rows: 2 + :widths: 7 5 4 4 4 4 5 5 4 4 4 7 7 7 6 6 6 6 + + * - Bit(s) + - 71:69 + - 68 + - 67 + - 66 + - 65 + - 64 + - 63:61 + - 60 + - 59 + - 58:55 + - 54:45 + - 44:39 + - 38:31 + - 30:23 + - 22:15 + - 14:7 + - 6:0 + * - **Field** + - HEADER + - AI_H + - AI_L + - DF_H + - DF_L + - COND + - ADDR_MODE + - WR + - UF + - RDI + - ADDR_SRC0 + - ADDR_SRC1 + - DATA_SRC + - (unused) + - (unused) + - (unused) + - (unused) + * - **Value** + - 101 + - see table + - see table + - see table + - see table + - 0-7 + - see table + - 0/1 + - 0/1 + - 0/1 + - varies + - varies + - varies + - 0 + - 0 + - 0 + - 0 + +**Field Descriptions:** + +.. list-table:: DMEM_WR Fields + :header-rows: 1 + :widths: 15 15 70 + + * - Field + - Bits + - Description + * - HEADER + - 71:69 + - Always 101 for memory write instructions + * - AI (Address Immediate) + - 68:66 + - Address mode selector (see table below) + * - DF (Data Format) + - 65:64 + - Source data format (00=32-bit immediate, 01=24-bit, 10=16-bit, 11=register only) + * - COND + - 63:61 + - Condition code for conditional execution (0-7) + * - ADDR_MODE + - 60:58 + - 000=literal, 001=register, 010=indexed literal, 011=indexed register + * - WR (Write Register) + - 57 + - 1 = Second Data Task present (-wr) + * - UF (Update Flag) + - 56 + - 1 = Update ALU flags + * - RDI (Register Destination Immediate) + - 55 + - 0 = ALU source for SDT, 1 = Immediate source for SDT + * - ADDR_SRC0 + - 54:45 + - First address component (register or immediate) + * - ADDR_SRC1 + - 44:39 + - Second address component (register, for indexed modes) + * - DATA_SRC + - 38:31 + - Data to write (register address or immediate value) + +**Address Modes (ADDR_MODE bits 60:58):** + +.. list-table:: + :header-rows: 1 + :widths: 15 20 20 45 + + * - ADDR_MODE + - Mode + - Syntax + - Description + * - 000 + - Literal + - ``[&imm]`` + - Address is immediate value + * - 001 + - Register + - ``[rX]`` + - Address is in register + * - 010 + - Indexed Literal + - ``[rX + &imm]`` + - Address = register + immediate offset + * - 011 + - Indexed Register + - ``[rX + rY]`` + - Address = register + register + +**AI Field Encoding (bits 68:66):** + +.. list-table:: + :header-rows: 1 + :widths: 15 20 65 + + * - AI + - Meaning + - Description + * - 000 + - ADDR_SRC0 is register + - First address component is a register address + * - 001 + - ADDR_SRC0 is immediate (11-bit) + - First address component is an immediate value + * - 010 + - ADDR_SRC1 is register + - Second address component is a register (for indexed modes) + * - 100 + - ADDR_SRC1 is immediate + - Second address component is immediate (rare) + +**Assembly Syntax:** + +.. code-block:: text + + DMEM_WR [&10] imm #42 ; Literal addressing + DMEM_WR [r1] op -op(r0) ; Register addressing + DMEM_WR [r1+&4] imm #5 ; Indexed literal + DMEM_WR [r2+r3] imm #1 ; Indexed register + DMEM_WR [&10] imm #42 -wr(r5 op) -op(r0+r1) ; With SDT + +5.13.2. WMEM_WR (Wave Memory Write) - Header=101 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The WMEM_WR instruction writes the 168-bit r_wave register to Wave Parameter Memory. + +**Bit Encoding:** + +.. list-table:: WMEM_WR Instruction (72-bit encoding) + :header-rows: 2 + :widths: 8 7 4 4 4 4 4 6 4 4 7 10 10 24 + + * - Bit(s) + - 71:69 + - 68 + - 67 + - 66 + - 65 + - 64 + - 63:61 + - 60 + - 59 + - 58:55 + - 54:45 + - 44:39 + - 38:0 + * - **Field** + - HEADER + - AI_H + - AI_L + - DF_H + - DF_L + - WW + - (unused) + - WP + - TI + - ADDR_MODE + - ADDR_SRC + - DATA_SRC + - (unused) + * - **Value** + - 101 + - see table + - see table + - see table + - see table + - 0/1 + - 0 + - 0/1 + - 0/1 + - see table + - varies + - varies + - 0 + +**Field Descriptions:** + +.. list-table:: WMEM_WR Fields + :header-rows: 1 + :widths: 15 15 70 + + * - Field + - Bits + - Description + * - HEADER + - 71:69 + - Always 101 for memory write instructions + * - WW (Write Wave) + - 64 + - 1 = This is a second wave task (SWT), 0 = primary task + * - WP (Write Port) + - 59 + - 1 = Second port task present (-wp) + * - TI (Time Immediate) + - 58 + - For SPT: 0 = use s_out_time, 1 = use immediate time + * - ADDR_MODE + - 57:56 + - 00 = Literal, 01 = Register + * - ADDR_SRC + - 55:45 + - WMEM address (immediate or register address) + * - DATA_SRC + - 44:39 + - Source of data (always r_wave, field may be unused) + +**Address Modes for WMEM:** + +.. list-table:: + :header-rows: 1 + :widths: 15 20 20 45 + + * - ADDR_MODE + - Mode + - Syntax + - Description + * - 00 + - Literal + - ``[&imm]`` + - Address is immediate (10-bit) + * - 01 + - Register + - ``[rX]`` + - Address from register (5-bit register address) + +**Assembly Syntax:** + +.. code-block:: text + + WMEM_WR [&5] ; Write r_wave to WMEM address 5 + WMEM_WR [r0] ; Write r_wave to address in r0 + WMEM_WR [&5] -wr(r1 imm) #100 ; With SDT + WMEM_WR [&5] -wp(p1) ; With SPT (second port task) + +5.14. Register Instructions - Bit Field Reference +-------------------------------------------------- + +Instructions with `HEADER = 100` (binary) write to registers (DREG, SREG, WREG, or r_wave). + +5.14.1. REG_WR (Register Write) - Header=100 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The REG_WR instruction writes data to a register from various sources (immediate, ALU, DMEM, WMEM). + +**Bit Encoding:** + +.. list-table:: REG_WR Instruction (72-bit encoding) + :header-rows: 2 + :widths: 7 5 4 4 4 4 5 5 5 5 5 5 7 7 7 10 10 + + * - Bit(s) + - 71:69 + - 68 + - 67 + - 66 + - 65 + - 64 + - 63:61 + - 60 + - 59 + - 58:55 + - 54:50 + - 49:39 + - 38:31 + - 30:23 + - 22:15 + - 14:0 + * - **Field** + - HEADER + - AI_H + - AI_L + - DF_H + - DF_L + - DST_BANK + - DST_IDX + - SRC_TYPE + - WR + - UF + - RDI + - ALU_OP + - SRC_A + - SRC_B + - IMM_DATA + - (unused) + * - **Value** + - 100 + - see table + - see table + - see table + - see table + - see table + - reg index + - see table + - 0/1 + - 0/1 + - 0/1 + - see table + - varies + - varies + - varies + - 0 + +**Field Descriptions:** + +.. list-table:: REG_WR Fields + :header-rows: 1 + :widths: 15 15 70 + + * - Field + - Bits + - Description + * - HEADER + - 71:69 + - Always 100 for register write instructions + * - DST_BANK (Destination Bank) + - 68:67 + - 00 = DREG (r0-r31), 01 = SREG (s0-s15), 10 = WREG (w0-w5), 11 = r_wave (special) + * - DST_IDX (Destination Index) + - 66:61 + - Register index within the bank (0-31) + * - SRC_TYPE (Source Type) + - 60:58 + - 000 = ALU operation (-op), 001 = DMEM, 010 = WMEM, 011 = Immediate + * - WR (Write Register for SDT) + - 57 + - 1 = Second Data Task present + * - UF (Update Flag) + - 56 + - 1 = Update ALU flags + * - RDI (Register Destination Immediate) + - 55 + - For SDT: 0 = ALU source, 1 = Immediate source + * - ALU_OP + - 54:50 + - ALU operation code (for SRC_TYPE=000) + * - SRC_A + - 49:39 + - First source register address + * - SRC_B + - 38:31 + - Second source register address (or immediate value for some modes) + * - IMM_DATA + - 30:0 + - Immediate data value (when SRC_TYPE=011 or part of ALU operation) + +**Destination Bank Encoding (bits 68:67):** + +.. list-table:: + :header-rows: 1 + :widths: 15 15 20 50 + + * - DST_BANK + - Bank + - Registers + - Example + * - 00 + - DREG + - r0-r31 + - ``REG_WR r5 ...`` + * - 01 + - SREG + - s0-s15 + - ``REG_WR s_cfg ...`` + * - 10 + - WREG + - w0-w5 + - ``REG_WR w_freq ...`` + * - 11 + - r_wave + - (special) + - ``REG_WR r_wave ...`` + +**Source Type Encoding (bits 60:58):** + +.. list-table:: + :header-rows: 1 + :widths: 15 20 65 + + * - SRC_TYPE + - Source + - Description + * - 000 + - ALU (-op) + - Source is result of ALU operation + * - 001 + - DMEM + - Source is Data Memory (requires address) + * - 010 + - WMEM + - Source is Wave Memory (requires address, destination must be r_wave) + * - 011 + - Immediate + - Source is immediate value (#value) + +**ALU Operation Codes (bits 54:50) - when SRC_TYPE=000:** + +.. list-table:: + :header-rows: 1 + :widths: 15 15 70 + + * - ALU_OP + - Operation + - Example + * - 00000 + - ADD + - ``-op(r0 + r1)`` + * - 00001 + - SUB + - ``-op(r0 - r1)`` + * - 00010 + - AND + - ``-op(r0 AND r1)`` + * - 00011 + - ASR + - ``-op(r0 ASR #2)`` + * - 00100 + - ABS + - ``-op(ABS r0)`` + * - 00101 + - MSH + - ``-op(MSH r0)`` + * - 00110 + - LSH + - ``-op(LSH r0)`` + * - 00111 + - SWP + - ``-op(SWP r0)`` + * - 01000 + - NOT + - ``-op(NOT r0)`` + * - 01001 + - OR + - ``-op(r0 OR r1)`` + * - 01010 + - XOR + - ``-op(r0 XOR r1)`` + * - 01110 + - SL + - ``-op(r0 SL #2)`` + * - 01111 + - SR + - ``-op(r0 SR #2)`` + +**Assembly Syntax:** + +.. code-block:: text + + REG_WR r0 imm #100 ; Immediate source + REG_WR r1 op -op(r0 + r2) ; ALU source + REG_WR r2 dmem [&10] ; DMEM source + REG_WR r_wave wmem [&5] ; WMEM source (to r_wave) + REG_WR s_addr label LOOP ; Label address to s_addr + REG_WR r0 op -op(r0 + #1) -uf -wr(r1 imm) #100 ; With SDT + +5.15. Configuration Instructions - Bit Field Reference +------------------------------------------------------- + +Instructions with `HEADER = 000` (binary) perform configuration operations without writing data. + +5.15.1. NOP (No Operation) - Header=000 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The NOP instruction does nothing and takes one cycle. + +**Bit Encoding:** + +.. list-table:: NOP Instruction (72-bit encoding) + :header-rows: 2 + :widths: 20 20 60 + + * - Bit(s) + - 71:69 + - 68:0 + * - **Field** + - HEADER + - (unused) + * - **Value** + - 000 + - 0 + +**Assembly Syntax:** + +.. code-block:: text + + NOP + +5.15.2. TEST (Test and Update Flags) - Header=000 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The TEST instruction performs an ALU operation and updates flags without writing a register. + +**Bit Encoding:** + +.. list-table:: TEST Instruction (72-bit encoding) + :header-rows: 2 + :widths: 10 7 5 5 5 5 5 7 5 5 10 10 10 20 + + * - Bit(s) + - 71:69 + - 68 + - 67 + - 66 + - 65 + - 64 + - 63:61 + - 60 + - 59 + - 58:50 + - 49:39 + - 38:31 + - 30:0 + * - **Field** + - HEADER + - AI_H + - AI_L + - DF_H + - DF_L + - (unused) + - COND + - UF + - RDI + - ALU_OP + - SRC_A + - SRC_B + - (unused) + * - **Value** + - 000 + - see table + - see table + - see table + - see table + - 0 + - 0-7 + - 1 + - 0/1 + - see table + - varies + - varies + - 0 + +**Field Descriptions:** + +.. list-table:: TEST Fields + :header-rows: 1 + :widths: 15 15 70 + + * - Field + - Bits + - Description + * - HEADER + - 71:69 + - Always 000 for configuration instructions + * - COND + - 63:61 + - Condition code (typically 000 for ALWAYS) + * - UF + - 60 + - Must be 1 to update flags + * - RDI + - 59 + - 0 = ALU operation, 1 = Immediate (rare for TEST) + * - ALU_OP + - 58:50 + - ALU operation code (same as REG_WR) + * - SRC_A + - 49:39 + - First source register address + * - SRC_B + - 38:31 + - Second source register address or immediate value + +**Assembly Syntax:** + +.. code-block:: text + + TEST -op(r0 - #1) -uf ; Test if r0-1 == 0 or negative + TEST -op(s_status AND #8) -uf ; Test DIV_DT_NEW bit + TEST -op(r1 - #32768) -uf ; Compare with threshold + + +5.16. Branch Instructions - Bit Field Reference +----------------------------------------------- + +Instructions with `HEADER = 001` (binary) control program flow by modifying the Program Counter (PC). + +.. note:: + The 72-bit word structure for port (5.12) and branch (5.16) instructions is + ``HEADER_AI_DF__COND__{BT/CFG}___ADDR____DATA__RD``. The authoritative + encoding lives in ``qick_lib/qick/tprocv2_assembler.py`` (``Instruction.BRANCH``, + ``Instruction.PORT_WR``) and ``firmware/rtl_lib/processors/qcore_cpu.sv``. + The tables below describe field semantics; exact bit positions should be + verified against those sources. + +5.16.1. JUMP (Conditional Branch) - Header=001 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The JUMP instruction changes the PC to a specified address, conditionally or unconditionally. + +**Bit Encoding:** + +.. list-table:: JUMP Instruction (72-bit encoding) + :header-rows: 2 + :widths: 7 5 4 4 4 4 6 4 4 4 4 4 4 7 10 10 + + * - Bit(s) + - 71:69 + - 68 + - 67:66 + - 65:63 + - 62:61 + - 60 + - 59 + - 58 + - 57 + - 56 + - 55 + - 54:50 + - 49:39 + - 38:31 + - 30:0 + * - **Field** + - HEADER + - AI + - DF + - COND + - BT + - UF + - WR + - RDI + - (rsvd) + - (rsvd) + - (rsvd) + - ALU_OP + - ADDR + - DATA + - RD + * - **Value** + - 001 + - see table + - see table + - 0-7 + - see table + - 0/1 + - 0/1 + - 0/1 + - 0 + - 0 + - 0 + - see table + - varies + - varies + - 0 + +**Field Descriptions:** + +.. list-table:: JUMP Fields + :header-rows: 1 + :widths: 15 15 70 + + * - Field + - Bits + - Description + * - HEADER + - 71:69 + - Always 001 for branch instructions + * - AI (Address Immediate) + - 68 + - 1 = Address is immediate 11-bit literal, 0 = Address is from ``s_addr`` (s15) register + * - DF (Data Format) + - 67:66 + - Data format for SDT (if present); same encoding as other instructions + * - COND + - 65:63 + - Condition code for conditional execution (0-7, see Condition Codes table) + * - BT (Branch Type) + - 62:61 + - ``00`` = JUMP, ``10`` = CALL, ``11`` = RET. ``01`` is reserved. + * - UF (Update Flag) + - 60 + - 1 = Update ALU flags from the SDT ALU operation + * - WR (Write Register / SDT) + - 59 + - 1 = Second Data Task present (``-wr(...)``) + * - RDI + - 58 + - For SDT: 0 = ALU source (``-op``), 1 = Immediate source (``imm``) + * - ALU_OP + - 54:50 + - ALU operation code for SDT (if WR=1); same encoding as ``-op`` in REG_WR + * - ADDR + - 49:39 (11-bit) or 54:49 (6-bit) + ... + - Jump target: 11-bit immediate address (AI=1) or register address (AI=0, ``s_addr``) + * - DATA + - 38:0 + - Source data for SDT (if WR=1): immediate or register address + +**Branch Type (BT) Encoding (bits 62:61):** + +.. list-table:: Branch Type (BT) Encoding + :header-rows: 1 + :widths: 15 20 65 + + * - BT + - Instruction + - Description + * - ``00`` + - JUMP + - Unconditional or conditional branch + * - ``10`` + - CALL + - Branch with return address pushed to stack (8-deep hardware stack) + * - ``11`` + - RET + - Return from subroutine (pop address from stack) + * - ``01`` + - (RFU) + - Reserved + +**Address Modes (AI bit 68):** + +.. list-table:: + :header-rows: 1 + :widths: 15 20 65 + + * - AI + - Mode + - Description + * - 1 + - Immediate + - Address is 11-bit immediate value encoded in the ADDR field + * - 0 + - Register + - Address is read from ``s_addr`` (s15) register + +**Special Address Constants (assembler-only):** + +.. list-table:: + :header-rows: 1 + :widths: 20 20 60 + + * - Constant + - Meaning + - Effect + * - ``HERE`` + - Current address + - `PC = PC` (infinite loop) + * - ``PREV`` + - Previous instruction + - `PC = PC - 1` + * - ``NEXT`` + - Next instruction + - `PC = PC + 1` + * - ``SKIP`` + - Skip one instruction + - `PC = PC + 2` + +**Condition Codes (COND bits 65:63):** + +.. list-table:: + :header-rows: 1 + :widths: 15 20 15 50 + + * - COND + - Condition + - Code + - Description + * - 000 + - ALWAYS + - (always) + - Unconditional jump + * - 001 + - Z + - Zero + - Jump if Zero flag = 1 + * - 010 + - S + - Sign (Negative) + - Jump if Sign flag = 1 + * - 011 + - NZ + - Non-Zero + - Jump if Zero flag = 0 + * - 100 + - NS + - Not Sign + - Jump if Sign flag = 0 + * - 101 + - F + - Flag + - Jump if selected flag is high + * - 110 + - NF + - Not Flag + - Jump if selected flag is low + * - 111 + - RFU + - - + - Reserved + +**Assembly Syntax:** + +.. code-block:: text + + JUMP LABEL ; Unconditional jump to LABEL + JUMP LABEL -if(NZ) ; Conditional jump if not zero + JUMP HERE -if(Z) ; Infinite loop if zero flag set + JUMP PREV -if(S) ; Jump to previous instruction + JUMP s_addr ; Jump to address in s_addr + JUMP LABEL -wr(r0 op) -op(r0 - #1) -uf ; Jump with SDT (decrement counter) + +5.16.2. CALL (Subroutine Call) - Header=001 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The CALL instruction saves the current PC to the stack and jumps to the specified address. + +**Bit Encoding:** + +.. list-table:: CALL Instruction (72-bit encoding) + :header-rows: 2 + :widths: 10 8 4 4 4 4 4 8 4 4 4 42 + + * - Bit(s) + - 71:69 + - 68 + - 67 + - 66 + - 65 + - 64 + - 63:61 + - 60 + - 59 + - 58 + - 57:0 + * - **Field** + - HEADER + - AI_H + - AI_L + - DF_H + - DF_L + - BT + - COND + - UF + - WR + - RDI + - ADDR_SRC + * - **Value** + - 001 + - see table + - see table + - see table + - see table + - 1 + - 0-7 + - 0/1 + - 0/1 + - 0/1 + - varies + +**Field Descriptions:** + +.. list-table:: CALL Fields + :header-rows: 1 + :widths: 15 15 70 + + * - Field + - Bits + - Description + * - HEADER + - 71:69 + - Always 001 for branch instructions + * - BT (Branch Type) + - 64 + - 1 = CALL (0 = JUMP) + * - COND + - 63:61 + - Condition code (0-7) - CALL can be conditional! + * - ADDR_SRC + - 57:0 + - Target address (immediate or register) + * - UF, WR, RDI + - 60,59,58 + - Same as JUMP - for SDT support + +**Stack Operation:** + +- Pushes current PC (return address) to hardware stack +- Stack depth is 256 levels +- Stack is **only** for return addresses, not local variables + +**Assembly Syntax:** + +.. code-block:: text + + CALL SUBROUTINE ; Call subroutine + CALL SUBROUTINE -if(NZ) ; Conditional call + CALL s_addr ; Call address in s_addr + CALL SUBROUTINE -wr(r0 imm) #1 ; Call with SDT + +5.16.3. RET (Return from Subroutine) - Header=001 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The RET instruction pops the return address from the stack and jumps back to the caller. + +**Bit Encoding:** + +.. list-table:: RET Instruction (72-bit encoding) + :header-rows: 2 + :widths: 10 8 4 4 4 4 4 8 4 4 4 42 + + * - Bit(s) + - 71:69 + - 68 + - 67 + - 66 + - 65 + - 64 + - 63:61 + - 60 + - 59 + - 58 + - 57:0 + * - **Field** + - HEADER + - AI_H + - AI_L + - DF_H + - DF_L + - BT + - COND + - UF + - WR + - RDI + - (unused) + * - **Value** + - 001 + - 0 + - 0 + - 0 + - 0 + - 2 + - 7 + - 0/1 + - 0/1 + - 0/1 + - 0 + +**Field Descriptions:** + +.. list-table:: RET Fields + :header-rows: 1 + :widths: 15 15 70 + + * - Field + - Bits + - Description + * - HEADER + - 71:69 + - Always 001 for branch instructions + * - BT (Branch Type) + - 64 + - 10 or 2? (RET is a special encoding) + * - COND + - 63:61 + - Typically 111 (ALWAYS) - RET is normally unconditional + * - UF, WR, RDI + - 60,59,58 + - For SDT support (rarely used with RET) + +**Stack Operation:** + +- Pops return address from hardware stack +- PC = popped address +- Stack depth decreases by 1 + +**Assembly Syntax:** + +.. code-block:: text + + RET ; Return to caller + RET -wr(r0 op) -op(r0 + #1) ; Return with SDT (rare) + +5.16.4. Summary: Branch Instructions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: Branch Instruction Summary + :header-rows: 1 + :widths: 20 15 20 45 + + * - Instruction + - Header + - BT Bit + - Description + * - JUMP + - 001 + - 0 + - Conditional/unconditional branch + * - CALL + - 001 + - 1 + - Branch with stack push (return address) + * - RET + - 001 + - 10 (special) + - Return from CALL (stack pop) + +**Pipeline Behavior:** + +.. list-table:: + :header-rows: 1 + :widths: 20 20 60 + + * - Instruction + - Latency + - Pipeline Effect + * - JUMP (taken) + - 2 cycles + - Pipeline flushed, 2 instruction slots wasted + * - JUMP (not taken) + - 1 cycle + - No flush, continues normally + * - CALL + - 2 cycles + - Pipeline flush + stack push + * - RET + - 2 cycles + - Pipeline flush + stack pop + +**Conditional Branch Optimization:** + +Branch instructions cause a 2-cycle penalty when taken. For simple conditional execution, use conditional instruction execution instead: + +.. code-block:: text + + ; Instead of: + ; JUMP SKIP -if(Z) + ; REG_WR r0 imm #1 + ; SKIP: + + ; Do this (no branch penalty): + REG_WR r0 imm #1 -if(NZ) + +**Stack Depth:** Maximum 256 nested CALLs. Exceeding this will overwrite the stack (undefined behavior). + +5.16.5. Branch Instructions with SDT (Second Data Task) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +All branch instructions can include a Second Data Task (-wr) that executes **before** the branch is taken. + +.. code-block:: text + + JUMP LOOP -wr(r0 op) -op(r0 - #1) -uf -if(NZ) + ; 1. Decrement r0 and update flags + ; 2. If NZ flag set, jump to LOOP + ; If NZ flag not set, fall through + +**Use case:** Loop counter management in a single instruction. + +.. code-block:: text + + REG_WR r0 imm #10 + LOOP: + ; ... loop body ... + JUMP LOOP -wr(r0 op) -op(r0 - #1) -uf -if(NZ) + ; Decrement and branch in one instruction + + +------------------------------------------------------------------------------- + +6. Time Management +================== + +6.1. Time Variables Recap +------------------------- + +- ``t_abs``: 48‑bit counter, runs at DAC frequency (t_clk). Counts absolute time since last reset. +- ``t_ref``: 48‑bit reference. Defines where user time = 0. +- ``t_usr = t_abs - t_ref``: user time, available in ``s_usr_time``. +- ``t_out_user``: 32‑bit signed value you specify in port writes. +- ``t_abs_out = t_ref + t_out_user``: absolute time when output will occur. + +**Why signed t_out_user?** +You can schedule outputs with a **negative** offset, meaning "output at time X relative +to reference, even if reference is in the past". This is useful for synchronizing with +other boards or for pre‑calculated sequences where the reference moves. + +6.2. TIME Instructions +---------------------- + +.. code-block:: text + + TIME rst // t_abs = 0, t_ref = 0, core resets + TIME set_ref rX // t_ref = rX (t_abs unchanged) + TIME inc_ref #N // t_ref = t_ref + N + TIME updt #N // t_abs = t_abs + N (rarely used) + +**Typical initialization sequence:** + +.. code-block:: text + + TIME rst // start from zero + // ... wait for external trigger ... + TIME set_ref r0 // once triggered, set t_ref to current t_abs (so t_usr becomes 0) + +6.3. Scheduling Outputs +------------------------ + +**Fixed time (immediate):** + +.. code-block:: text + + WPORT_WR p0 r_wave @1000 // output at t_usr = 1000 + +**Relative to previous output:** + +.. code-block:: text + + REG_WR s_out_time imm #1000 + WPORT_WR p0 r_wave @s_out_time + REG_WR s_out_time op -op(s_out_time + #500) + WPORT_WR p0 r_wave @s_out_time // 500 cycles after first + +**Variable time from register:** + +.. code-block:: text + + REG_WR r0 imm #2000 + WPORT_WR p0 r_wave @r0 // @r0 is allowed? Check syntax. + +**Note:** The assembler accepts ``@rX`` (time from register) but the manual shows only immediate or s_out_time. Verify. + +6.4. Waiting for a Specific Time +-------------------------------- + +.. code-block:: text + + WAIT time @5000 // pause execution until t_usr >= 5000 + +6.5. Reset and Initialization Sequence +--------------------------------------- + +A proper initialization sequence ensures predictable behavior. + +**Complete Initialization Checklist:** + +.. code-block:: text + + ; 1. Reset everything + TIME rst + + ; 2. Configure data sources (if using peripherals) + REG_WR s_cfg imm src_arith + + ; 3. Clear stale flags + CLEAR arith + CLEAR div + CLEAR port + + ; 4. Initialize time registers + REG_WR s_out_time imm #1000 + + ; 5. Load initial waveform parameters + REG_WR w_freq imm #0x1000000 + REG_WR w_phase imm #0 + REG_WR w_gain imm #32768 + REG_WR w_length imm #1024 + + ; 6. Save to WMEM (optional) + WMEM_WR [&0] + + ; 7. Initialize loop counters + REG_WR r0 imm #100 + + ; 8. Start main program + JUMP MAIN + +**What TIME rst does:** + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Component + - Effect + * - t_abs, t_ref + - Set to 0 + * - Program Counter + - Set to 0 + * - All registers (r, s, w) + - Cleared to 0 + * - FIFOs + - Flushed + * - AXI registers + - NOT cleared + * - LFSR (s_rand) + - NOT cleared + +**Python Initialization:** + +.. code-block:: python + + from qick import QickSoc + + soc = QickSoc() + tproc = soc.tproc + + # Reset time and core + tproc.time_reset() + + # Load program binary (list of 32-bit words) + tproc.load_bin_program(prog_bin, load_mem=True) + + # Start execution + tproc.start() + + # Stop execution + tproc.stop() + + # Read DMEM + data = tproc.read_dmem(addr=0x10, length=100) + + # Write DMEM (buffers) + tproc.load_dmem(buff_in=data, addr=0x20) + + # Config registers are plain Python properties, not raw single_read/ + # single_write (those exist but the driver marks them "Do not use! + # Use the DMA instead" -- see set_lfsr_cfg() for this specific example) + tproc.set_lfsr_cfg(mode=2) # core_cfg LFSR field = 2 (advance-on-read) + val = tproc.core_cfg # read back the whole core_cfg register + + # External flag + tproc.set_axi_flg() + tproc.clr_axi_flg() + + +------------------------------------------------------------------------------- + +7. Input/Output Programming +=========================== + +7.1. Output Ports +----------------- + +**Data ports (DPORT)**: 32‑bit digital outputs + +.. code-block:: text + + DPORT_WR p0 imm 0x12345678 @1000 + DPORT_WR p2 reg r5 @2000 + +**Trigger ports (TRIG)**: 1‑bit outputs (set high or low) + +.. code-block:: text + + TRIG p0 set @150 // output 1 + TRIG p0 clr @200 // output 0 + +**Wave ports (WPORT)**: 168‑bit waveform parameters + +.. code-block:: text + + WPORT_WR p1 r_wave @1000 // from r_wave + WPORT_WR p1 wmem [&5] @2000 // from WMEM address 5 + +7.2. Input Ports (Feedback) +--------------------------- + +Input ports receive data from ADCs or other sources via AXI‑Stream. + +**Reading a single port (64 bits total):** + +.. code-block:: text + + WAIT port_dt // wait until any input port has new data + DPORT_RD p0 // read port 0 -> s_port_l (lower 32) and s_port_h (upper 32) + REG_WR r0 op -op(s_port_l) // use lower part + +**Checking which port received data (advanced):** + +The ``s_status`` register has bits 31:16 indicating which port has fresh data. You can test individual bits. + +.. code-block:: text + + // Wait specifically for port 2 (bit 18) + WAIT_PORT2: + TEST -op(s_status AND #(1<<18)) + JUMP WAIT_PORT2 -if(Z) + DPORT_RD p2 + +7.3. External Flag (Python to tProc) +------------------------------------ + +Python can set or clear an external flag that the tProc can test with ``-if(F)`` or ``-if(NF)``. + +**From Python:** + +.. code-block:: python + + soc.tproc.set_external_flag() # sets bit 13 of tproc_ctrl + soc.tproc.clear_external_flag() # sets bit 14 + +**In assembly:** + +.. code-block:: text + + WAIT_FOR_FLAG: + REG_WR r0 imm #0 -if(NF) // do nothing if flag not set + JUMP WAIT_FOR_FLAG -if(NF) // loop if flag not set + // flag is set, proceed + +------------------------------------------------------------------------------- + +.. _tproc-peripherals: + +8. Peripherals Deep Dive +======================== + +8.1. ARITH (Multiply‑Accumulate) +-------------------------------- + +The ARITH unit is the most powerful peripheral. It can replace multiple ALU instructions. + +**Configuration before using ARITH:** + +.. code-block:: text + + // 1. Set data source for s_core_r1 to ARITH + REG_WR s_cfg imm src_arith + + // 2. Clear any old new‑data flag + REG_WR s_ctrl imm clr_arith + +**Start an ARITH operation:** + +.. code-block:: text + + ARITH T r1 r2 // r1 * r2 (4 cycles) + +**Wait for completion** (no ``WAIT`` macro for this -- poll by hand, see +:ref:`5.10.3 `): + +.. code-block:: text + + TEST -op(s_status AND #2) -uf + JUMP HERE -if(Z) + +**Read the result (64 bits):** + +.. code-block:: text + + ; Lower 32 bits via s_arith_low (s3) + REG_WR r_low op -op(s_arith_low) + + ; Upper 32 bits via AXI read (READ_SEL = 4 -> TPROC_R_DT = {low, high}) + ; or by reading s_arith_low twice (the register bank presents the full + ; 64-bit result as two consecutive 32-bit reads when selected by DT_SRC). + +**Note:** The ARITH unit produces a 64‑bit result. ``s_arith_low`` (s3) always +holds the lower 32 bits. The full 64-bit result is available through the AXI +``TPROC_R_DT`` register when ``READ_SEL = 4`` (``src_arith``). + +8.2. DIV (Integer Division) +--------------------------- + +Division is slow (32 cycles) but non‑blocking: the CPU continues execution while DIV works in the background. + +**Best practice:** Start a division early, do other work, then check for completion. + +.. code-block:: text + + // Start division early + DIV r1 r2 + + // Do other useful work while division runs + REG_WR r3 op -op(r3 + #100) + REG_WR r4 op -op(r4 - #50) + + // Wait for division to complete + WAIT div_dt + REG_WR r5 op -op(s_div_q) // quotient + REG_WR r6 op -op(s_div_r) // remainder + +8.3. LFSR (Random Number Generator) +------------------------------------ + +Configure via ``core_cfg`` AXI register. + +**Modes:** + +- 0: Stop (do not advance) +- 1: Free running (advance every c_clk cycle) +- 2: Advance when read +- 3: Advance when written (write any value to s_rand) + +**Example: advance‑on‑read mode** + +.. code-block:: text + + // Configure from Python (soc.tproc.set_lfsr_cfg(mode=2) -- see qick.drivers.tproc) + + // In assembly: each read gives a new random number + REG_WR r0 op -op(s_rand) // first random + REG_WR r1 op -op(s_rand) // second random (different) + +------------------------------------------------------------------------------- + +.. _tproc-examples: + +9. Task‑Based Examples (Copy‑Paste Ready) +========================================== + +9.1. Generate a Single Pulse +---------------------------- + +.. code-block:: text + + .ADDR 0x00 + // Configure waveform + REG_WR w_freq imm #0x1000000 // 1 MHz (example) + REG_WR w_phase imm #0 + REG_WR w_gain imm #32768 // half amplitude + REG_WR w_length imm #1000 // 1000 samples + REG_WR w_conf imm #0 + + // Output at time 1000 + WPORT_WR p1 r_wave @1000 + .END + +9.2. Generate a Pulse Train +--------------------------- + +.. code-block:: text + + .ADDR 0x00 + REG_WR r0 imm #10 // number of pulses + REG_WR s_out_time imm #1000 // start time + + LOOP: + WPORT_WR p1 r_wave @s_out_time + REG_WR s_out_time op -op(s_out_time + #500) // 500 cycle spacing + REG_WR r0 op -op(r0 - #1) -uf + JUMP LOOP -if(NZ) + .END + +9.3. Conditional Pulse Based on ADC Value +------------------------------------------ + +.. code-block:: text + + .ADDR 0x00 + // Initialization + REG_WR s_out_time imm #1000 + REG_WR r0 imm #100 + + // Configure waveform A (long pulse) + REG_WR w_freq imm #0x1000000 + REG_WR w_gain imm #32768 + REG_WR w_length imm #2000 + REG_WR w_conf imm #0 + // Save a copy to WMEM + WMEM_WR [&0] + + // Configure waveform B (short pulse) + REG_WR w_length imm #500 + WMEM_WR [&1] + + // Main loop + REG_WR r0 imm #100 // number of experiments + + EXPERIMENT: + WAIT port_dt // wait for ADC data + DPORT_RD p0 // read port 0 + REG_WR r1 op -op(s_port_l) // r1 = ADC value + REG_WR r1 op -op(r1 - #32768) -uf // compare with threshold + + // Select waveform based on comparison + ; Note: REG_WR with wmem source cannot be conditional. + ; Use an unconditional load after setting r_wave via an intermediate register. + REG_WR r2 op -op(r1) -if(NS) // r2 = r1 (copy) if ADC >= 32768 + REG_WR r_wave wmem [&0] // long pulse (default) + REG_WR r_wave wmem [&1] -if(S) // short pulse if ADC < 32768 + ; Alternatively, use a TEST + JUMP pattern instead of conditional REG_WR. + + WPORT_WR p1 r_wave @s_out_time + REG_WR s_out_time op -op(s_out_time + #2000) // wait for next experiment + + REG_WR r0 op -op(r0 - #1) -uf + JUMP EXPERIMENT -if(NZ) + .END + +9.4. Frequency Sweep (Chirp) +---------------------------- + +.. code-block:: text + + .ADDR 0x00 + REG_WR r0 imm #100 // number of steps + REG_WR r1 imm #0x1000000 // start frequency + REG_WR s_out_time imm #1000 + +LOOP: + REG_WR w_freq op -op(r1) + WPORT_WR p1 r_wave @s_out_time + REG_WR r1 op -op(r1 + #0x10000) // increment frequency + REG_WR s_out_time op -op(s_out_time + #500) + REG_WR r0 op -op(r0 - #1) -uf + JUMP LOOP -if(NZ) + .END + +9.5. Wait for External Trigger (from Python flag) +-------------------------------------------------- + +.. code-block:: text + + .ADDR 0x00 + // Wait for Python to set external flag + WAIT_TRIG: + JUMP WAIT_TRIG -if(NF) // loop while flag is 0 + // Flag is set, continue + WPORT_WR p1 r_wave @1000 + .END + +From Python: + +.. code-block:: python + + soc.tproc.set_external_flag() # triggers the tProc + +9.6. Read and Accumulate ADC Data +--------------------------------- + +.. code-block:: text + + .ADDR 0x00 + REG_WR r0 imm #0 // accumulator + REG_WR r1 imm #100 // number of samples + +LOOP: + WAIT port_dt + DPORT_RD p0 + REG_WR r0 op -op(r0 + s_port_l) // accumulate + REG_WR r1 op -op(r1 - #1) -uf + JUMP LOOP -if(NZ) + + // Store result to DMEM + DMEM_WR [&0] imm r0 // result at DMEM address 0 + .END + +------------------------------------------------------------------------------- + +10. System Configuration (Hardware Parameters) +============================================== + +The tProcessor can be configured at synthesis time (in the FPGA bitstream) to match your needs. The following parameters trade off resource usage against capabilities. + +10.1. Memory Sizes +------------------ + +.. list-table:: + :header-rows: 1 + + * - Parameter + - Width (bits) + - Minimum + - Maximum + - Default (QICK) + - When to increase + * - PMEM_AW (Program Memory address bits) + - 2^AW words + - 8 (256 words) + - 16 (65536) + - 8 (256 words) + - Complex programs with many instructions + * - DMEM_AW (Data Memory address bits) + - 2^AW words + - 8 (256) + - 16 (65536) + - 8 (256) + - Large lookup tables or data buffers + * - WMEM_AW (Wave Memory address bits) + - 2^AW words + - 8 (256) + - 11 (2048) + - 8 (256) + - Many pre‑computed waveforms + * - REG_AW (Number of data registers) + - 2^AW registers + - 4 (16 registers) + - 5 (32 registers) + - 4 (16 registers) + - Usually fine at 32 + +10.2. FIFO Depths +----------------- + +.. list-table:: + :header-rows: 1 + + * - Parameter + - Default + - Maximum + - Resource cost + * - FIFO_DEPTH (all three FIFOs) + - 8 (tprocv2 core) / 9 (packaged IP top) + - 512 + - Increases BRAM usage + +**Choosing FIFO depth:** Set to the maximum number of pending port writes you may have. If your program writes 20 ports between waiting periods, set depth ≥ 20. + +10.3. Port Counts +----------------- + +.. list-table:: + :header-rows: 1 + + * - Parameter + - Default (QICK) + - Maximum + * - IN_PORT_QTY (input ports) + - 1 + - 16 + * - OUT_TRIG_QTY (trigger ports) + - 2 + - 8 + * - OUT_DPORT_QTY (data ports) + - 1 + - 4 + * - OUT_DPORT_DW (data port width, bits) + - 4 + - 32 + * - OUT_WPORT_QTY (wave ports) + - 1 + - 16 + +**Note:** Increasing port counts increases FPGA resource usage and may reduce maximum clock frequency. + +------------------------------------------------------------------------------- + +11. Complete Instruction Reference (Alphabetical) +================================================== + +11.1. ARITH +----------- + +**Purpose:** Start a multiply‑accumulate operation on the DSP. + +**Syntax:** ``ARITH op A B [C] [D]`` + +**Operation codes (selected by ``alu_op_i[3:0]``; the DSP macro's A/D inputs share a pre-adder, so the form is ``(A op D) * B [+|- C]``):** + +- ``T`` : ``A * B`` +- ``TP`` : ``A * B + C`` +- ``TM`` : ``A * B - C`` +- ``PT`` : ``(D + A) * B`` +- ``PTP``: ``(D + A) * B + C`` +- ``PTM``: ``(D + A) * B - C`` +- ``MT`` : ``(D - A) * B`` +- ``MTP``: ``(D - A) * B + C`` +- ``MTM``: ``(D - A) * B - C`` + +**Operand widths (DSP48E2):** A and D = 27 bits, B = 18 bits, C = 32 bits, result = 46 bits (sign-extended to 64 bits in ``sreg_arith``). + +**Latency:** 4 c_clk cycles (the DSP macro is held busy for 4 cycles; ``arith_rdy`` goes low while working and returns high when done). + +**Flags affected:** None (but sets ``ARITH_DT_NEW`` in ``s_status`` after the result is captured). + +**Example:** ``ARITH T r1 r2`` + +11.2. CALL +---------- + +**Purpose:** Call a subroutine (save PC to stack). + +**Syntax:** ``CALL address`` + +**Address can be:** label, immediate (&addr), or s_addr. + +**Latency:** 2 cycles (branch penalty) + +**Max nesting:** 8 (hardware stack depth, fixed in ``tpv2_stack``) + +**Example:** ``CALL MY_SUB`` + +11.3. CLEAR (macro) +------------------- + +**Purpose:** Clear ``_NEW`` flag in s_status. + +**Syntax:** ``CLEAR option`` + +**Options:** ``arith``, ``div``, ``port``, ``qnet`` + +**Expands to:** ``REG_WR s_ctrl imm value`` + +**Example:** ``CLEAR arith`` + +11.4. DIV +--------- + +**Purpose:** Start unsigned 32‑bit integer division. + +**Syntax:** ``DIV numerator denominator`` + +- numerator: register +- denominator: register or 24‑bit immediate + +**Latency:** 32 cycles (non‑blocking) + +**Results:** s_div_q (quotient), s_div_r (remainder) + +**Example:** ``DIV r1 r2`` + +11.5. DMEM_WR +------------- + +**Purpose:** Write to Data Memory. + +**Syntax:** ``DMEM_WR [address] source`` + +**Address modes:** +- ``[&imm]`` – literal +- ``[rX]`` – register +- ``[rX + &imm]`` – indexed literal +- ``[rX + rY]`` – indexed register + +**Source:** ``imm #value`` or ``op -op(...)`` + +**Example:** ``DMEM_WR [&10] imm #42`` + +11.6. DPORT_RD +-------------- + +**Purpose:** Read input port. + +**Syntax:** ``DPORT_RD port`` + +**Result:** s_port_l (lower 32 bits), s_port_h (upper 32 bits) + +**Sets:** PORT_DT_NEW flag for that port (cleared by read or CLEAR port) + +**Example:** ``DPORT_RD p0`` + +11.7. DPORT_WR +-------------- + +**Purpose:** Write 32‑bit data to output port. + +**Syntax:** ``DPORT_WR port source [time]`` + +**Source:** ``imm #value`` or ``reg rX`` + +**Time:** ``@imm`` or ``@s_out_time`` (default = s_out_time) + +**Example:** ``DPORT_WR p0 imm 1 @1000`` + +11.8. FLAG +---------- + +**Purpose:** Modify internal flag. + +**Syntax:** ``FLAG operation`` + +**Operations:** ``set``, ``clr``, ``inv`` + +**Example:** ``FLAG set`` + +11.9. JUMP +---------- + +**Purpose:** Conditional or unconditional branch. + +**Syntax:** ``JUMP address -if(condition)`` + +**Address:** label, ``HERE``, ``PREV``, ``NEXT``, ``SKIP``, immediate, or s_addr + +**Latency:** 2 cycles if taken + +**Example:** ``JUMP LOOP -if(NZ)`` + +11.10. NOP +---------- + +**Purpose:** No operation. + +**Syntax:** ``NOP`` + +**Latency:** 1 cycle + +11.11. REG_WR +------------- + +**Purpose:** Write to register (r, s, or w). + +**Syntax:** ``REG_WR destination source`` + +**Source:** ``imm #value``, ``op -op(...)``, ``dmem [addr]``, ``wmem [addr]``, ``label address`` + +**Example:** ``REG_WR r0 imm #100`` + +11.12. RET +---------- + +**Purpose:** Return from subroutine. + +**Syntax:** ``RET`` + +**Latency:** 2 cycles + +11.13. TEST +----------- + +**Purpose:** Perform ALU operation and update flags without writing a register. + +**Syntax:** ``TEST -op(operation) -uf`` + +**Example:** ``TEST -op(r0 - #1) -uf`` + +11.14. TIME +----------- + +**Purpose:** Control time counters. + +**Syntax:** ``TIME operation [value]`` + +**Operations:** ``rst``, ``set_ref``, ``inc_ref``, ``updt`` + +**Example:** ``TIME rst`` + +11.15. TRIG +----------- + +**Purpose:** Set or clear trigger output. + +**Syntax:** ``TRIG port operation [time]`` + +**Operation:** ``set`` or ``clr`` + +**Time:** ``@imm`` or ``@s_out_time`` + +**Example:** ``TRIG p0 set @150`` + +11.16. WAIT (macro) +------------------- + +**Purpose:** Wait for condition. + +**Syntax:** ``WAIT condition`` + +**Conditions:** ``time @N``, ``div_rdy``, ``div_dt``, ``qpa_rdy``, ``qpa_dt``, +``port_dt`` -- this is the **complete** list recognized by +``Instruction.WAIT()`` in ``tprocv2_assembler.py``; anything else +(including ``arith_rdy``/``arith_dt``) raises ``RuntimeError: No +Recognized Operation``. See :ref:`5.10.3 ` for how +to wait on ARITH by hand. + +**Example:** ``WAIT time @1000`` + +11.17. WMEM_WR +-------------- + +**Purpose:** Write r_wave to Wave Parameter Memory. + +**Syntax:** ``WMEM_WR [address]`` + +**Address:** ``[&imm]`` or ``[rX]`` + +**Example:** ``WMEM_WR [&5]`` + +11.18. WPORT_WR +--------------- + +**Purpose:** Write waveform to wave port. + +**Syntax:** ``WPORT_WR port source [time]`` + +**Source:** ``r_wave`` or ``wmem [addr]`` + +**Example:** ``WPORT_WR p1 r_wave @1000`` + +------------------------------------------------------------------------------- + +12. Python API Reference +======================== + +12.1. Initializing the tProcessor +--------------------------------- + +.. code-block:: python + + from qick import QickSoc + from qick.tprocv2_assembler import Assembler + + # Connect to the RFSoC board + soc = QickSoc() + + # Access the tProcessor instance + tproc = soc.tproc + +12.2. Loading a Program +----------------------- + +**From an assembly string:** + +.. code-block:: python + + asm_code = \"\"\" + .ADDR 0x00 + REG_WR r0 imm #100 + DPORT_WR p0 reg r0 @1000 + .END + \"\"\" + prog_bin = Assembler.str_asm2bin(asm_code) + tproc.load_bin_program(prog_bin, load_mem=True) + +**From a list of instructions (dictionary format):** + +.. code-block:: python + + prog_list = [ + {'CMD': 'REG_WR', 'DST': 'r0', 'SRC': 'imm', 'LIT': 100}, + {'CMD': 'DPORT_WR', 'DST': '0', 'SRC': 'reg', 'DATA': 'r0', 'TIME': 1000}, + ] + prog_bin = Assembler.list2bin(prog_list) + tproc.load_bin_program(prog_bin, load_mem=True) + +12.3. Controlling Execution +--------------------------- + +.. code-block:: python + + tproc.time_reset() # Reset time and core + tproc.start() # Start execution + tproc.stop() # Stop execution + tproc.core_start() # Reset and start only core (time continues) + tproc.core_stop() # Stop only core + +12.4. Reading Status and Data +----------------------------- + +.. code-block:: python + + # Human-readable status/debug dumps (see §13.8 for details) -- these are + # the recommended way to inspect tProc state; raw single_read/single_write + # exist on the driver but are explicitly marked "Do not use! Use the + # DMA instead" in their own docstrings. + tproc.print_status() # core/time FSM state, *_rdy/*_dt_new flags + tproc.print_debug() # FIFO flags, DIV/ARITH/QNET/QCOM/port/rand values + + # Read from DMEM + data = tproc.read_dmem(addr=0x10, length=100) + + # Write to DMEM + tproc.load_dmem(buff_in=data, addr=0x20) + +12.5. Configuring the LFSR +-------------------------- + +.. code-block:: python + + # Modes: 0=stop, 1=free run, 2=advance on read, 3=advance on write + tproc.set_lfsr_cfg(mode=2) # advance on read + +------------------------------------------------------------------------------- + +13. Python Examples +=================== + +This section provides practical examples of using the tProcessor v2 from Python. +For complete API documentation, see Chapter 12. + +.. note:: + Earlier revisions of this chapter showed a low-level workflow (hand-written + ``WPORT_WR`` assembly strings, manual ``Waveform``/DMEM packing, and + ``soc.avg_bufs[i].set_avg_mode()``/``set_nsamp()``/``get_data()``) that + doesn't match ``qick_lib`` -- those buffer methods don't exist on the + driver, and ``Waveform`` actually lives in ``qick.asm_v2``, not + ``qick.qick_asm``. The examples below use the real, current + :class:`.QickProgram`-based workflow (the same one used throughout + :doc:`/sg_v6`, :doc:`/readout`, and :doc:`/generators`), verified against + ``qick.asm_v2``/``qick.qick_asm``/``qick.drivers.tproc`` in this session. + Raw assembly is still shown where it's genuinely the right tool -- true + hardware-timed conditional branching (:ref:`tproc-conditional-feedback`) + can't be expressed any other way -- but even there, the surrounding + Python (loading/running/reading back) uses real, verified calls. + +.. contents:: + :local: + :depth: 2 + +13.1. Basic Python Workflow +--------------------------- + +Normal QICK programs are written as a :class:`.QickProgram` subclass (most +often :class:`.AveragerProgramV2`): declare your generator/readout channels +once in ``_initialize()``, define named pulses, then play them by name in +``_body()``. The framework handles WMEM/PMEM loading, timing, and +reps/rounds for you. + +.. code-block:: python + + from qick import * + + soc = QickSoc() + + class BasicPulse(AveragerProgramV2): + def _initialize(self, cfg): + self.declare_gen(ch=0, nqz=1) + self.add_pulse(ch=0, name="tone", style="const", + freq=100.0, phase=0, gain=0.5, length=1.0) + # MHz, degrees, -1..1, us + + def _body(self, cfg): + self.pulse(ch=0, name="tone", t=0) + + prog = BasicPulse(soccfg, reps=1, final_delay=1.0, cfg={}) + prog.acquire(soc) # no readouts declared -> just plays the pulse once per rep + +13.2. Basic Loopback Demo (Send and Receive Pulse) +--------------------------------------------------- + +This example sends a pulse and captures its raw (decimated) waveform on a +readout channel -- see :doc:`topics/readout_modes` for accumulated +(``acquire()``) vs. decimated (``acquire_decimated()``) readout. + +.. code-block:: python + + from qick import * + + soc = QickSoc() + + class LoopbackProgram(AveragerProgramV2): + def _initialize(self, cfg): + self.declare_readout(ch=0, length=3.0, freq=100.0, gen_ch=0) + self.declare_gen(ch=0, nqz=1) + self.add_pulse(ch=0, name="pulse0", style="const", + freq=100.0, phase=0, gain=0.5, length=1.0) + + def _body(self, cfg): + self.trigger(ros=[0], t=0) # arm readout channel 0 + self.pulse(ch=0, name="pulse0", t=0) + self.delay_auto(t=1.0) # wait for pulse+readout before looping + + # single shot, decimated (raw waveform) readout + prog = LoopbackProgram(soccfg, reps=1, final_delay=10.0, cfg={}) + iq = prog.acquire_decimated(soc) + print(f"Acquired {len(iq[0])} samples") + +.. _tproc-conditional-feedback: + +13.3. Conditional Feedback Demo +------------------------------- + +Real-time conditional branching -- e.g. active qubit reset, only playing a +pulse if a measurement crossed a threshold -- must happen inside the +tProc's own instruction stream (no Python round-trip is fast enough), but +you write it with high-level Python calls, not hand-assembled instructions: +:meth:`.QickProgramV2.read_and_jump` combines a readout-register read with a +conditional jump, and :meth:`.QickProgramV2.label` marks the jump target. +This condensed example is adapted from the full working version in +:doc:`tutorials/04_Real_Time_Feedback`. + +.. code-block:: python + + from qick import * + + soc = QickSoc() + + class ActiveResetProgram(AveragerProgramV2): + def _initialize(self, cfg): + self.declare_gen(ch=cfg['gen_ch'], nqz=1) + self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'], + freq=cfg['freq'], gen_ch=cfg['gen_ch']) + + self.add_pulse(ch=cfg['gen_ch'], name="measure_pulse", style="const", + freq=cfg['freq'], phase=0, gain=1.0, length=cfg['pulse_len']) + self.add_pulse(ch=cfg['gen_ch'], name="reset_pulse", style="const", + freq=cfg['freq'], phase=0, gain=1.0, length=cfg['reset_len']) + + def _body(self, cfg): + # Measure + self.pulse(ch=cfg['gen_ch'], name="measure_pulse", t=0) + self.trigger(ros=[cfg['ro_ch']], t=cfg['trig_time']) + self.wait_auto(cfg['read_wait']) + self.delay_auto(cfg['read_wait'] + cfg['extra_delay']) + + # If I >= threshold (qubit measured in excited state), play reset pulse + self.read_and_jump(ro_ch=cfg['ro_ch'], component='I', + threshold=cfg['threshold'], test='>=', label='NO_RESET') + self.pulse(ch=cfg['gen_ch'], name="reset_pulse", t=0) + self.label("NO_RESET") + + config = {'gen_ch': 0, 'ro_ch': 0, 'freq': 500.0, 'trig_time': 0.25, + 'read_wait': 0.1, 'extra_delay': 0.2, 'threshold': 0, + 'ro_len': 0.1, 'pulse_len': 0.025, 'reset_len': 0.05} + + prog = ActiveResetProgram(soccfg, reps=100, final_delay=0.5, cfg=config) + prog.acquire(soc) + +13.4. Frequency Sweep (Chirp) +----------------------------- + +A frequency sweep is a loop level (:meth:`.QickProgramV2.add_loop`) with a +pulse parameter set to :func:`.QickSweep1D`, rather than a manually +incremented register -- the tProc itself steps the frequency each +iteration, hardware-timed. + +.. code-block:: python + + from qick import * + + soc = QickSoc() + + class ChirpProgram(AveragerProgramV2): + def _initialize(self, cfg): + self.declare_gen(ch=0, nqz=1) + self.add_loop("freq_loop", cfg['steps']) + self.add_pulse(ch=0, name="chirp", style="const", + freq=QickSweep1D("freq_loop", cfg['start_freq'], cfg['end_freq']), + phase=0, gain=0.5, length=cfg['pulse_len']) + + def _body(self, cfg): + self.pulse(ch=0, name="chirp", t=0) + self.delay_auto(t=0.5) + + cfg = {'steps': 100, 'start_freq': 50.0, 'end_freq': 150.0, 'pulse_len': 0.1} + prog = ChirpProgram(soccfg, reps=1, final_delay=1.0, cfg=cfg) + prog.acquire(soc) + +13.5. Complete Example: Send Pulse and Capture Echo +---------------------------------------------------- + +This example combines everything: DAC pulse, ADC capture, and data analysis. + +.. code-block:: python + + from qick import * + import numpy as np + import matplotlib.pyplot as plt + + soc = QickSoc() + + class EchoProgram(AveragerProgramV2): + def _initialize(self, cfg): + self.declare_gen(ch=0, nqz=1) + self.declare_readout(ch=0, length=cfg['ro_len'], freq=cfg['freq'], gen_ch=0) + self.add_pulse(ch=0, name="probe", style="const", + freq=cfg['freq'], phase=0, gain=cfg['gain'], length=cfg['pulse_len']) + + def _body(self, cfg): + self.trigger(ros=[0], t=0) + self.pulse(ch=0, name="probe", t=0) + self.delay_auto(t=1.0) + + cfg = {'freq': 50.0, 'gain': 0.5, 'pulse_len': 1.0, 'ro_len': 2.0} + prog = EchoProgram(soccfg, reps=1, final_delay=10.0, cfg=cfg) + iq = prog.acquire_decimated(soc) # raw waveform for one readout channel + + # --- Analyze --- + data_i, data_q = iq[0][:, 0], iq[0][:, 1] + amplitude = np.sqrt(data_i**2 + data_q**2) + + plt.plot(prog.get_time_axis(ro_index=0), amplitude) + plt.xlabel("Time (us)") + plt.ylabel("Amplitude") + plt.title("Pulse Echo") + plt.show() + + print(f"Peak amplitude: {np.max(amplitude)}") + print(f"Noise floor: {np.mean(amplitude[:100])}") + +13.6. Integration with Signal Generator v6 +------------------------------------------ + +The Signal Generator v6 (SG-v6) is one of several waveform generation +cores QICK supports for DAC outputs -- see :doc:`/generators` for the full +family and :doc:`/firmware` for how many channels of which type your +specific board has (it varies by board, see :ref:`std-firmware-per-board`). + +For complete documentation and worked Python examples (basic pulse, shaped +envelope, queued pulses), see :doc:`/sg_v6`'s "Python Usage" section -- +they use the same :meth:`.QickProgram.declare_gen`/ +:meth:`.QickProgram.add_pulse`/:meth:`.QickProgram.pulse` pattern as every +other example in this chapter. + +13.7. Integration with Readout System +------------------------------------- + +The readout system captures ADC data, triggered by a dedicated single-bit +``trig_N_o`` pin per buffer instance (see :ref:`tproc-ports` in +:doc:`/firmware` for the full pin model -- it is *not* a bit within a +channel-numbered data word). QICK supports several readout variants +(single-tone, tProc-configured, and channelized/PFB) -- see :doc:`/readout` +for the family overview and :ref:`std-firmware-per-board` for which +variant(s) your board uses. + +For the normal workflow (:meth:`.QickProgram.declare_readout`, +:meth:`.QickProgramV2.trigger`, :meth:`.AcquireMixin.acquire`/ +:meth:`.AcquireMixin.acquire_decimated`), see :doc:`/readout`'s "Python +Interface" section, or the worked examples earlier in this chapter (all of +which declare and trigger a readout channel the same way). + +13.8. Debugging and Monitoring +------------------------------ + +.. note:: + Earlier revisions of this section built examples around + ``soc.tproc.single_read``/``single_write`` -- these exist on the driver + (``qick.drivers.tproc.Axis_QICK_Proc``) but their own docstrings say + **"Do not use! Use the DMA instead"**, and the code has a real bug (an + undefined variable). Use the methods below instead. + +**Reading tProc status and debug state from Python:** + +``soc.tproc`` (:class:`.Axis_QICK_Proc`) has two built-in, human-readable +dumps -- no manual register decoding needed: + +.. code-block:: python + + soc.tproc.print_status() + # prints core/time FSM state, enable bits, all the *_dt_new/*_rdy flags + # (div, arith, qnet, qcom, qp1, qp2), decoded from the status register + + soc.tproc.print_debug() + # prints FIFO empty/full flags per peripheral, plus DIV/ARITH/QNET/QCOM/ + # QPA/QPB/port/rand debug read-back values + +You can also print the board/processor configuration once, up front, as a +sanity check before debugging further: + +.. code-block:: python + + soc.tproc.info() # prints instantiated parameters (memory sizes, + # which optional peripherals are present, clocks) + print(soccfg) # full board config: every generator/readout/buffer + +13.9. Performance Measurement +----------------------------- + +**Wall-clock timing from Python** (includes PS-PL DMA and Python overhead, +not just tProc execution time -- useful for overall experiment throughput): + +.. code-block:: python + + import time + + start = time.perf_counter() + iq = prog.acquire(soc, progress=False) + print(f"acquire() took {time.perf_counter() - start:.3f} s") + +**Hardware-precise timing with an oscilloscope**, using a spare PMOD +trigger pin bracketing the section of interest -- this measures actual +tProc/firmware timing, unaffected by PS-side overhead: + +.. code-block:: text + + ; in raw assembly, or via QickProgram's pins= argument to trigger() + TRIG p0 set @start_time + ; ... section to measure ... + TRIG p0 clr @end_time + +13.10. Repository of Examples +----------------------------- + +This documentation's own tutorial notebooks (:doc:`topics/tutorials`) are +the primary worked-example resource, all runnable on real hardware (or, for +tutorials 00-07, on the :doc:`topics/tutorials`'s Colab-runnable emulator +port): + +.. list-table:: Tutorial Notebooks Covering This Chapter's Topics + :header-rows: 1 + :widths: 45 55 + + * - Notebook + - Covers + * - :doc:`tutorials/01_Basic_Sequencing` + - Basic pulses, sequences, acquisition (§13.1-13.2) + * - :doc:`tutorials/04_Real_Time_Feedback` + - Conditional pulses, active reset, thresholding (§13.3) + * - :doc:`tutorials/02_Parameter_Sweeps` + - 1D/2D sweeps with ``QickSweep1D``/``add_loop`` (§13.4) + * - :doc:`tutorials/06_Generators_And_Readouts` + - Generators, readouts, I/Q mixing (§13.5-13.7) + +13.11. Where to Find More Examples +---------------------------------- + +For more elaborate examples (multi-qubit experiments, advanced feedback +loops, calibration routines), refer to: + +- **Tutorial series** (:doc:`topics/tutorials`) – The full 00-14 series, + from basic sequencing through streaming/DSP, custom firmware + integration, and XCOM multi-board network synchronization. +- **Official QICK Demos Repository** – + `github.com/openquantumhardware/qick/tree/main/qick_demos `_. +- **Community Contributions** – Check the ``#qick`` channel on the + `Unitary Fund Discord `_ for + user-contributed examples and support. +- **QICK Papers** – See :doc:`/papers` for academic papers that include + example use cases and code snippets. + +------------------------------------------------------------------------------- + +.. _tproc-pitfalls: + +14. Common Pitfalls and Debugging +================================== + +14.1. Pitfall: Forgetting to Wait for Peripherals +------------------------------------------------- + +**Wrong:** + +.. code-block:: text + + ARITH T r1 r2 + REG_WR r3 op -op(s_arith_low) // reads stale data! + +**Correct:** + +.. code-block:: text + + ARITH T r1 r2 + TEST -op(s_status AND #2) -uf // no WAIT macro for arith_dt -- poll by hand + JUMP HERE -if(Z) + REG_WR r3 op -op(s_arith_low) + +14.2. Pitfall: FIFO Overflow +---------------------------- + +**Symptom:** Program stalls unexpectedly. + +**Check:** ``s_status[15]`` (FIFO_FULL) + +**Fix:** Increase FIFO depth in hardware, or add delays between port writes. + +14.3. Pitfall: Branch Penalty in Tight Loops +-------------------------------------------- + +**Symptom:** Loop takes longer than expected. + +**Example of inefficient loop:** + +.. code-block:: text + + LOOP: + // ... code ... + JUMP LOOP -if(NZ) // 2 cycle penalty each iteration + +**Better: use conditional execution or unroll.** + +14.4. Pitfall: Using s_out_time Incorrectly +-------------------------------------------- + +**Wrong:** + +.. code-block:: text + + WPORT_WR p0 r_wave @1000 + WPORT_WR p0 r_wave @2000 // second write uses immediate 2000 + +**Correct (using s_out_time for incremental timing):** + +.. code-block:: text + + REG_WR s_out_time imm #1000 + WPORT_WR p0 r_wave @s_out_time + REG_WR s_out_time op -op(s_out_time + #1000) + WPORT_WR p0 r_wave @s_out_time + +14.5. Debugging Technique: Single Step +--------------------------------------- + +From Python: + +.. code-block:: python + + soc.tproc.core_step() # execute one instruction, then stop + +You can single‑step through your program to see where it gets stuck. + +14.6. Debugging Technique: Read Debug Register +---------------------------------------------- + +.. code-block:: python + + soc.tproc.print_status() # core/time FSM state, enable bits, *_rdy/*_dt_new flags + soc.tproc.print_debug() # FIFO empty/full flags, DIV/ARITH/QNET/QCOM/port/rand values + +See §13.8 ("Debugging and Monitoring") for details on these two methods -- +they replace manual register decoding via ``single_read``, which the +driver itself flags as "Do not use". + +14.7. Common Issues Quick Reference +------------------------------------ + +.. list-table:: + :header-rows: 1 + :widths: 40 55 + + * - Symptom + - Likely cause and fix + * - Output never appears on port + - FIFO full (check ``s_status[15]``); or ``abs_time`` already past ``out_abs_time`` + * - Flag condition never triggers + - Condition flag set in instruction N but tested in N+1 (2-cycle lag). Insert NOPs. + * - DIV/ARITH results wrong + - Reading result before ``_DT_NEW`` is set. Use ``WAIT div_dt`` for DIV; + for ARITH there's no ``WAIT`` macro, poll ``s_status`` bit 1 by hand + (:ref:`5.10.3 `). + * - Jump goes to wrong place + - Using ``[]`` around a label: ``JUMP [LABEL]`` is wrong; use ``JUMP LABEL``. + * - Time does not advance + - ``TIME`` instructions issued < 5 cycles apart. Insert NOPs. + * - ``s_addr``-based JUMP misbehaves + - Address written to ``s15`` too close to JUMP. Insert at least 2 NOPs after writing ``s15``. + +------------------------------------------------------------------------------- + +15. FAQ (Frequently Asked Questions) +==================================== + +**Q1: Can I use floating‑point numbers?** +A: No. The tProc only supports integer arithmetic. Pre‑compute floats in Python and convert to fixed‑point (e.g., scale by 2^16). + +**Q2: What is the maximum program size?** +A: Up to 65536 instructions (64 bits each) if configured with PMEM_AW=16. Default is 1024 instructions. + +**Q3: How accurate is the timing?** +A: The dispatcher compares times every t_clk cycle. Jitter is ±1 t_clk cycle (~2.6 ns at 384 MHz). The 5‑cycle write‑to‑output latency is deterministic. + +**Q4: Can I interrupt the tProc?** +A: Not in the current version. The tProc runs to completion or until stopped by Python. + +**Q5: How do I synchronize two tProcessors on different boards?** +A: Use the SYNC signal (abs_time bit 29) or external triggers. Distribute a common reference clock. + +**Q6: What happens when time overflows (48 bits)?** +A: Time rolls over to 0. For long experiments, reset time periodically or use relative timing. + +**Q7: Can I use a register as a time value in @?** +A: The assembler supports ``@rX`` but this manual recommends using s_out_time for clarity. + +**Q8: Why does my program get stuck on WAIT div_dt?** +A: You may have forgotten to start a division (DIV) before waiting. Or the division completed long ago and you need to clear the flag. + +**Q9: How do I generate a sine wave?** +A: The signal generator (separate block) generates sine/cosine from DDS. The tProc only sends frequency/phase/gain parameters. + +**Q10: Can I read the same input port multiple times?** +A: Yes. Each read clears the PORT_DT_NEW flag for that port. New data will set it again. + +------------------------------------------------------------------------------- + +16. Glossary +============ + +.. list-table:: + :header-rows: 1 + + * - Term + - Definition + * - ALU + - Arithmetic Logic Unit. Performs integer operations. + * - AXI‑Lite + - Simple AXI protocol for register access. + * - AXI‑Stream + - Streaming AXI protocol for high‑bandwidth data. + * - CDC + - Clock Domain Crossing. Transferring data between different clock domains. + * - DDS + - Direct Digital Synthesizer. Generates sine/cosine waves. + * - Dispatcher + - Hardware block that compares time and updates outputs. + * - DMA + - Direct Memory Access. Transfers data without CPU involvement. + * - DMEM + - Data Memory. 32‑bit wide, for user data. + * - DSP48 + - FPGA DSP slice. Used for multiplication. + * - FIFO + - First‑In First‑Out queue. Holds scheduled outputs. + * - LFSR + - Linear Feedback Shift Register. Generates pseudo‑random numbers. + * - Pipeline + - Series of stages in the CPU. Allows overlapping instruction execution. + * - PMEM + - Program Memory. 64‑bit wide, stores instructions. + * - PRNG + - Pseudo‑Random Number Generator. See LFSR. + * - PS + - Processing System (ARM processor in the FPGA). + * - tProc + - timing Processor. Subject of this manual. + * - WMEM + - Wave Memory. 168‑bit wide, stores waveform parameters. + +------------------------------------------------------------------------------- + +*End of Document* diff --git a/docs/source/tutorials/00_Getting_Started.ipynb b/docs/source/tutorials/00_Getting_Started.ipynb new file mode 100644 index 000000000..bd3c09506 --- /dev/null +++ b/docs/source/tutorials/00_Getting_Started.ipynb @@ -0,0 +1,353 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 00 - Getting Started with QICK and tProc v2\n", + "\n", + "**Objective:** Verify your QICK installation, connect to the RFSoC board, and understand the basic hardware configuration." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Setup and Imports" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "QICK Version: 0.2.381\n" + ] + } + ], + "source": [ + "# Jupyter notebook setup\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import logging\n", + "\n", + "# Core QICK imports\n", + "from qick import *\n", + "\n", + "# tProc v2 specific classes\n", + "from qick.asm_v2 import AveragerProgramV2, QickSweep1D, QickSpan\n", + "\n", + "# Optional: increase logging level for debugging\n", + "# logging.basicConfig(level=logging.DEBUG)\n", + "logging.basicConfig(level=logging.INFO, format='%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s')\n", + "# Reduce noise from the tProc core\n", + "logging.getLogger(\"qick_processor\").setLevel(logging.WARNING)\n", + "\n", + "# Display the loaded QICK library version\n", + "print(f\"QICK Version: {qick.get_version()}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Explanation:** This cell imports all necessary libraries. The `qick.asm_v2` module contains the classes for building tProc v2 programs. The logging configuration helps with debugging if something goes wrong." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Connect to the RFSoC Board\n", + "\n", + "You need to provide the correct path to your firmware `.bit` file. This file is specific to your board model and the firmware version." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%pybind11/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "=== Board Connection Successful ===\n" + ] + } + ], + "source": [ + "# --- IMPORTANT: Change this path to point to your firmware file ---\n", + "# Common paths for different boards (examples):\n", + "# ZCU111: '/home/xilinx/jupyter_notebooks/qick_firmware/out/qick_zcu111.bit'\n", + "# RFSoC4x2: '/home/xilinx/jupyter_notebooks/qick_firmware/out/qick_4x2.bit'\n", + "# ZCU216: '/home/xilinx/jupyter_notebooks/qick_firmware/out/qick_216.bit'\n", + "\n", + "BITSTREAM_PATH = 'qick_216.bit'#'/path/to/your/firmware.bit' # <--- YOU MUST CHANGE THIS\n", + "\n", + "# Connect to the board\n", + "soc = QickSoc(BITSTREAM_PATH)\n", + "soccfg = soc # 'soccfg' is a common alias used throughout QICK examples\n", + "\n", + "print(\"\\n=== Board Connection Successful ===\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Inspect the Hardware Configuration\n", + "\n", + "The `QickSoc` object contains all the information about your firmware: clock frequencies, generator channels, readout channels, digital I/O, and tProc capabilities." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "QICK running on ZCU216, software version 0.2.381\n", + "\n", + "Firmware configuration (built Tue Sep 3 12:55:04 2024):\n", + "\n", + "\tGlobal clocks (MHz): tProc dispatcher timing 614.400, RF reference 245.760\n", + "\tGroups of related clocks: [tProc timing clock, DAC tile 2], [DAC tile 3], [ADC tile 2]\n", + "\n", + "\t5 signal generator channels:\n", + "\t0:\taxis_signal_gen_v6 - fs=9830.400 Msps, fabric=614.400 MHz\n", + "\t\tenvelope memory: 16384 complex samples (1.667 us)\n", + "\t\t32-bit DDS, range=9830.400 MHz\n", + "\t\tDAC tile 2, blk 0 is 0_230 on JHC3, or QICK box DAC port 8\n", + "\t1:\taxis_sg_int4_v2 - fs=6881.280 Msps, fabric=430.080 MHz\n", + "\t\tenvelope memory: 4096 complex samples (9.524 us)\n", + "\t\t32-bit DDS, range=1720.320 MHz\n", + "\t\tDAC tile 3, blk 0 is 0_231 on JHC3, or QICK box DAC port 12\n", + "\t2:\taxis_sg_int4_v2 - fs=6881.280 Msps, fabric=430.080 MHz\n", + "\t\tenvelope memory: 4096 complex samples (9.524 us)\n", + "\t\t32-bit DDS, range=1720.320 MHz\n", + "\t\tDAC tile 3, blk 1 is 1_231 on JHC4, or QICK box DAC port 13\n", + "\t3:\taxis_sg_mux8_v1 - fs=9830.400 Msps, fabric=614.400 MHz\n", + "\t\t32-bit DDS, range=9830.400 MHz\n", + "\t\tDAC tile 2, blk 2 is 2_230 on JHC3, or QICK box DAC port 10\n", + "\t4:\taxis_sg_mixmux8_v1 - fs=6881.280 Msps, fabric=430.080 MHz\n", + "\t\t32-bit DDS, range=1720.320 MHz\n", + "\t\tDAC tile 3, blk 2 is 2_231 on JHC3, or QICK box DAC port 14\n", + "\n", + "\t7 readout channels:\n", + "\t0:\taxis_dyn_readout_v1 - configured by tProc output 3\n", + "\t\tfs=2457.600 Msps, decimated=307.200 MHz, 32-bit DDS, range=2457.600 MHz\n", + "\t\taxis_avg_buffer v1.0 (no edge counter, no weights)\n", + "\t\tmemory 16384 accumulated, 1024 decimated (3.333 us)\n", + "\t\ttriggered by tport 0, pin 0, feedback to tProc input 0\n", + "\t\tADC tile 2, blk 0 is 0_226 on JHC7, or QICK box ADC port 4\n", + "\t1:\taxis_readout_v3 - configured by tProc output 3\n", + "\t\tfs=2457.600 Msps, decimated=614.400 MHz, 32-bit DDS, range=2457.600 MHz\n", + "\t\taxis_avg_buffer v1.0 (no edge counter, no weights)\n", + "\t\tmemory 16384 accumulated, 1024 decimated (1.667 us)\n", + "\t\ttriggered by tport 1, pin 0, feedback to tProc input 1\n", + "\t\tADC tile 2, blk 1 is 1_226 on JHC8, or QICK box ADC port 5\n", + "\t2:\taxis_pfb_readout_v3 - configured by PYNQ\n", + "\t\tfs=2457.600 Msps, decimated=38.400 MHz, 32-bit DDS, range=38.400 MHz\n", + "\t\taxis_avg_buffer v1.0 (no edge counter, no weights)\n", + "\t\tmemory 16384 accumulated, 1024 decimated (26.667 us)\n", + "\t\ttriggered by tport 2, pin 0, feedback to tProc input 2\n", + "\t\tADC tile 2, blk 2 is 2_226 on JHC7, or QICK box ADC port 6\n", + "\t3:\taxis_pfb_readout_v3 - configured by PYNQ\n", + "\t\tfs=2457.600 Msps, decimated=38.400 MHz, 32-bit DDS, range=38.400 MHz\n", + "\t\taxis_avg_buffer v1.0 (no edge counter, no weights)\n", + "\t\tmemory 16384 accumulated, 1024 decimated (26.667 us)\n", + "\t\ttriggered by tport 3, pin 0, feedback to tProc input 3\n", + "\t\tADC tile 2, blk 2 is 2_226 on JHC7, or QICK box ADC port 6\n", + "\t4:\taxis_pfb_readout_v3 - configured by PYNQ\n", + "\t\tfs=2457.600 Msps, decimated=38.400 MHz, 32-bit DDS, range=38.400 MHz\n", + "\t\taxis_avg_buffer v1.0 (no edge counter, no weights)\n", + "\t\tmemory 16384 accumulated, 1024 decimated (26.667 us)\n", + "\t\ttriggered by tport 4, pin 0, feedback to tProc input 4\n", + "\t\tADC tile 2, blk 2 is 2_226 on JHC7, or QICK box ADC port 6\n", + "\t5:\taxis_pfb_readout_v3 - configured by PYNQ\n", + "\t\tfs=2457.600 Msps, decimated=38.400 MHz, 32-bit DDS, range=38.400 MHz\n", + "\t\taxis_avg_buffer v1.0 (no edge counter, no weights)\n", + "\t\tmemory 16384 accumulated, 1024 decimated (26.667 us)\n", + "\t\ttriggered by tport 5, pin 0, feedback to tProc input 5\n", + "\t\tADC tile 2, blk 2 is 2_226 on JHC7, or QICK box ADC port 6\n", + "\t6:\taxis_readout_v2 - configured by PYNQ\n", + "\t\tfs=2457.600 Msps, decimated=307.200 MHz, 32-bit DDS, range=2457.600 MHz\n", + "\t\taxis_avg_buffer v1.0 (no edge counter, no weights)\n", + "\t\tmemory 16384 accumulated, 1024 decimated (3.333 us)\n", + "\t\ttriggered by tport 6, pin 0, feedback to tProc input 6\n", + "\t\tADC tile 2, blk 3 is 3_226 on JHC8, or QICK box ADC port 7\n", + "\n", + "\t8 digital output pins:\n", + "\t0:\tPMOD0_0_LS\n", + "\t1:\tPMOD0_1_LS\n", + "\t2:\tPMOD0_2_LS\n", + "\t3:\tPMOD0_3_LS\n", + "\t4:\tPMOD0_4_LS\n", + "\t5:\tPMOD0_5_LS\n", + "\t6:\tPMOD0_6_LS\n", + "\t7:\tPMOD0_7_LS\n", + "\n", + "\ttProc: qick_processor (\"v2\") rev 21, core execution clock 200.000 MHz\n", + "\t\tmemories (words): program 1024, data 1024, waveform 256\n", + "\t\texternal start pin: PMOD1_0_LS\n", + "\t\texternal stop pin: PMOD1_1_LS\n", + "\n", + "\tDDR4 memory buffer: 1073741824 samples (3.495 sec), 128 samples/transfer\n", + "\t\twired to readouts [0, 2, 3, 4, 5, 6]\n", + "\n", + "\tMR buffer: 8192 samples (3.333 us), wired to readouts [0, 6]\n" + ] + } + ], + "source": [ + "print(soccfg)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Explanation:** The printed output shows:\n", + "- **Global clocks:** tProc timing clock, RF reference frequency\n", + "- **Signal generators:** Number of channels, sample rates, envelope memory size\n", + "- **Readout channels:** Sample rates, buffer sizes, trigger mappings\n", + "- **Digital output pins:** Available PMOD pins\n", + "- **tProc configuration:** Program memory size, data memory size, waveform memory size, core clock\n", + "\n", + "This information is essential when configuring your experiments." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Quick Hardware Test\n", + "\n", + "To verify that the board is responding correctly, read the tProc's program counter and test data memory access." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tProc Program Counter: 0\n", + "Data memory read test: [0]\n", + "\n", + "✓ Basic board communication verified via program counter read.\n" + ] + } + ], + "source": [ + "# Read the tProc's program counter (should be 0 after reset)\n", + "pc = soc.get_tproc_counter(addr=1)\n", + "print(f\"tProc Program Counter: {pc}\")\n", + "\n", + "# Read a data memory address to verify communication\n", + "# Data memory address 0 should contain some value, but reading it confirms the interface works\n", + "try:\n", + " data = soc.read_mem(length=1, mem_sel='dmem', addr=0)\n", + " print(f\"Data memory read test: {data}\")\n", + "except Exception as e:\n", + " print(f\"Data memory read failed: {e}\")\n", + "\n", + "print(\"\\n✓ Basic board communication verified via program counter read.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Explanation:** These simple reads confirm that the communication with the board is working correctly. The tProc program counter should be 0 before we load a program." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Summary\n", + "\n", + "You are now ready to start writing QICK experiments. The next notebook ([``01_Basic_Sequencing.ipynb``](./01_Basic_Sequencing.ipynb)) will show you how to define and play pulses, and acquire data.\n", + "\n", + "**Key takeaways:**\n", + "- Use `QickSoc(path)` to connect to your board\n", + "- The `soccfg` object holds all hardware configuration information\n", + "- Always check that your firmware path is correct for your specific board\n", + "- Use `get_tproc_counter()` and `read_mem()` to verify board communication" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/source/tutorials/01_Basic_Sequencing.ipynb b/docs/source/tutorials/01_Basic_Sequencing.ipynb new file mode 100644 index 000000000..d0927b6ba --- /dev/null +++ b/docs/source/tutorials/01_Basic_Sequencing.ipynb @@ -0,0 +1,497 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 01 - Basic Sequencing with tProc v2\n", + "\n", + "**Objective:** Learn how to define pulses, create a sequence, acquire data, and understand the basic structure of a tProc v2 program." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%pybind11/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Standard imports\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import logging\n", + "\n", + "from qick import *\n", + "from qick.asm_v2 import AveragerProgramV2\n", + "\n", + "# Setup logging\n", + "logging.basicConfig(level=logging.INFO, format='%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s')\n", + "logging.getLogger(\"qick_processor\").setLevel(logging.WARNING)\n", + "\n", + "# Connect to the board (adjust the path to your firmware)\n", + "BITSTREAM_PATH = 'qick_216.bit'#'/path/to/your/firmware.bit' # <--- CHANGE THIS\n", + "soc = QickSoc(BITSTREAM_PATH)\n", + "soccfg = soc\n", + "\n", + "# Define hardware channels (adjust based on your firmware)\n", + "GEN_CH = 0 # Generator channel 0\n", + "RO_CH = 0 # Readout channel 0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Your First Program: The Structure\n", + "\n", + "Every tProc v2 program follows this pattern:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "class MyFirstProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " \"\"\"Setup: Called once when the program is compiled.\"\"\"\n", + " # 1. Declare hardware resources\n", + " # 2. Define envelopes and pulses\n", + " # 3. Configure readout\n", + " pass\n", + "\n", + " def _body(self, cfg):\n", + " \"\"\"Sequence: Called for each repetition (shot).\"\"\"\n", + " # 1. Play pulses\n", + " # 2. Trigger readout\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The key distinction:\n", + "- **`_initialize()`** runs during **compilation** (Python side, once)\n", + "- **`_body()`** runs during **execution** (tProc side, many times)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. A Simple Single-Pulse Program\n", + "\n", + "Let's create a program that plays a single constant pulse and measures it." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7adfd5d528074f1d98d29b424532fa4f", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/10 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "class SinglePulseProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " # Declare the generator and readout channels\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1) # nqz=1 means no frequency folding\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + "\n", + " # Define a constant pulse (no envelope shaping)\n", + " self.add_pulse(\n", + " ch=cfg['gen_ch'],\n", + " name=\"my_pulse\",\n", + " style=\"const\", # Constant amplitude\n", + " freq=cfg['freq'], # Frequency in MHz\n", + " length=cfg['pulse_len'], # Duration in microseconds\n", + " phase=cfg['phase'], # Phase in degrees\n", + " gain=cfg['gain'] # Amplitude (0 to 1)\n", + " )\n", + "\n", + " # Configure the readout\n", + " self.add_readoutconfig(\n", + " ch=cfg['ro_ch'],\n", + " name=\"my_ro\",\n", + " freq=cfg['freq'],\n", + " gen_ch=cfg['gen_ch']\n", + " )\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", t=0)\n", + "\n", + " def _body(self, cfg):\n", + " # Play the pulse at time t=0\n", + " self.pulse(ch=cfg['gen_ch'], name=\"my_pulse\", t=0)\n", + " # Trigger the readout\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'])\n", + "\n", + "# Configure the experiment\n", + "config = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500.0, # MHz\n", + " 'pulse_len': 0.1, # microseconds\n", + " 'phase': 0, # degrees\n", + " 'gain': 1.0, # full amplitude\n", + " 'trig_time': 0.2, # microseconds (when to start readout)\n", + " 'ro_len': 0.5 # microseconds (readout duration)\n", + "}\n", + "\n", + "# Create and run the program\n", + "prog = SinglePulseProgram(soccfg, reps=1, final_delay=0.5, cfg=config)\n", + "\n", + "# Acquire data (decimated mode gives IQ traces vs time)\n", + "iq_data = prog.acquire_decimated(soc, rounds=10) # 10 averages\n", + "time_axis = prog.get_time_axis(ro_index=0)\n", + "\n", + "# Plot the results\n", + "plt.figure(figsize=(10, 5))\n", + "plt.plot(time_axis, iq_data[0][:,0], label='I (In-phase)')\n", + "plt.plot(time_axis, iq_data[0][:,1], label='Q (Quadrature)')\n", + "plt.plot(time_axis, np.abs(iq_data[0].dot([1,1j])), label='Magnitude')\n", + "plt.legend()\n", + "plt.xlabel('Time (µs)')\n", + "plt.ylabel('Amplitude (a.u.)')\n", + "plt.title('Single Pulse Measurement')\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Explanation of the cell:**\n", + "- `declare_gen()` and `declare_readout()` tell the tProc which hardware resources we'll use\n", + "- `add_pulse()` defines a pulse with its parameters. A constant pulse (`style=\"const\"`) has flat amplitude.\n", + "- In `_body()`, `pulse()` schedules the pulse, and `trigger()` starts the readout acquisition\n", + "- `acquire_decimated()` returns averaged IQ data. The `rounds` parameter controls how many times the entire experiment is repeated for averaging." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Multiple Pulses in One Sequence\n", + "\n", + "You can define many pulses in `_initialize()` and play them in any order." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "70174dbcae064fab8d6b1a03dc8d8728", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/10 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "class MultiPulseProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + "\n", + " # Define a Gaussian envelope\n", + " ramp_len = 0.2\n", + " self.add_gauss(\n", + " ch=cfg['gen_ch'],\n", + " name=\"gauss_env\",\n", + " sigma=ramp_len/10,\n", + " length=ramp_len,\n", + " even_length=True\n", + " )\n", + "\n", + " # Define different pulse types\n", + " # Flat-top pulse (Gaussian rise/fall, constant middle)\n", + " self.add_pulse(\n", + " ch=cfg['gen_ch'], name=\"p_flattop\",\n", + " style=\"flat_top\", envelope=\"gauss_env\",\n", + " freq=cfg['freq'], length=0.1, phase=0, gain=1.0\n", + " )\n", + "\n", + " # Gaussian pulse\n", + " self.add_pulse(\n", + " ch=cfg['gen_ch'], name=\"p_gauss\",\n", + " style=\"arb\", envelope=\"gauss_env\",\n", + " freq=cfg['freq'], phase=0, gain=1.0\n", + " )\n", + "\n", + " # Constant pulse\n", + " self.add_pulse(\n", + " ch=cfg['gen_ch'], name=\"p_const\",\n", + " style=\"const\",\n", + " freq=cfg['freq'], length=0.15, phase=0, gain=1.0\n", + " )\n", + "\n", + " # Flat-top pulse with 90-degree phase\n", + " self.add_pulse(\n", + " ch=cfg['gen_ch'], name=\"p_flattop_90\",\n", + " style=\"flat_top\", envelope=\"gauss_env\",\n", + " freq=cfg['freq'], length=0.1, phase=90, gain=1.0\n", + " )\n", + "\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", freq=cfg['freq'], gen_ch=cfg['gen_ch'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", t=0)\n", + "\n", + " def _body(self, cfg):\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'], ddr4=True)\n", + "\n", + " # Sequence of pulses at different times (microseconds)\n", + " self.pulse(ch=cfg['gen_ch'], name=\"p_flattop\", t=0)\n", + " self.pulse(ch=cfg['gen_ch'], name=\"p_gauss\", t=0.4)\n", + " self.pulse(ch=cfg['gen_ch'], name=\"p_const\", t=0.8)\n", + " self.pulse(ch=cfg['gen_ch'], name=\"p_flattop_90\", t=1.2)\n", + " self.pulse(ch=cfg['gen_ch'], name=\"p_gauss\", t=1.6)\n", + "\n", + "# Run the multi-pulse sequence\n", + "config['ro_len'] = 2.0 # Longer readout to capture all pulses\n", + "prog = MultiPulseProgram(soccfg, reps=1, final_delay=0.5, cfg=config)\n", + "iq_data = prog.acquire_decimated(soc, rounds=10)\n", + "time_axis = prog.get_time_axis(ro_index=0)\n", + "\n", + "plt.figure(figsize=(12, 6))\n", + "plt.plot(time_axis, iq_data[0][:,0], label='I')\n", + "plt.plot(time_axis, iq_data[0][:,1], label='Q')\n", + "plt.plot(time_axis, np.abs(iq_data[0].dot([1,1j])), label='Magnitude')\n", + "plt.legend()\n", + "plt.xlabel('Time (µs)')\n", + "plt.ylabel('Amplitude (a.u.)')\n", + "plt.title('Multi-Pulse Sequence')\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Key observations from this example:**\n", + "- Once a pulse is defined, it can be reused multiple times (`p_gauss` appears twice)\n", + "- Different pulse styles serve different purposes: `const` for square pulses, `arb` for shaped pulses, `flat_top` for shaped pulses with a constant top\n", + "- The `even_length=True` parameter ensures the envelope has an even number of samples, which is required for some operations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Inspecting Your Program\n", + "\n", + "You can print the program to see what the tProc will execute:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "macros:\n", + "\tWriteReg(dst='s_core_w1', src=0)\n", + "\tConfigReadout(ch=0, name='my_ro', t=0, tag=None, t_params={'t': }, t_regs={'t': 0})\n", + "\tDelay(t=1.0, auto=True, gens=True, ros=True, tag=None, t_params={'t': }, t_regs={'t': 614})\n", + "\tOpenLoop(n=1, name='reps')\n", + "\tTrigger(ros=[0], tts=[], pins=[0], t=0.2, width=0.016276041666666668, ddr4=True, mr=False, tag=None, t_params={'t': , 'width': }, t_regs={'t': 123, 'width': 10}, outdict=defaultdict(, {0: 1}), trigset={0, 7})\n", + "\tPulse(ch=0, name='p_flattop', t=0, tag=None, t_params={'t': }, t_regs={'t': 0})\n", + "\tPulse(ch=0, name='p_gauss', t=0.4, tag=None, t_params={'t': }, t_regs={'t': 246})\n", + "\tPulse(ch=0, name='p_const', t=0.8, tag=None, t_params={'t': }, t_regs={'t': 492})\n", + "\tPulse(ch=0, name='p_flattop_90', t=1.2, tag=None, t_params={'t': }, t_regs={'t': 737})\n", + "\tPulse(ch=0, name='p_gauss', t=1.6, tag=None, t_params={'t': }, t_regs={'t': 983})\n", + "\tWait(t=0, auto=True, gens=False, ros=True, tag=None, no_warn=True, t_params={'t': }, t_regs={'t': 1351})\n", + "\tDelay(t=0.5, auto=True, gens=True, ros=True, tag=None, t_params={'t': }, t_regs={'t': 1658})\n", + "\tIncReg(dst='s_core_w1', src=1)\n", + "\tCloseLoop()\n", + "\tEnd()\n", + "registers:\n", + "\treps: QickRegisterV2(addr=0, init=None)\n", + "pulses:\n", + "\tp_flattop: QickPulse(waveforms=[Waveform(name='p_flattop_w0', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=32766, spans={}, quantize=2, steps={}), length=61, conf=8), Waveform(name='p_flattop_w1', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=16383, spans={}, quantize=1, steps={}), length=QickRawParam(par='length', start=61, spans={}, quantize=1, steps={}), conf=9), Waveform(name='p_flattop_w2', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=61, gain=QickRawParam(par='gain', start=32766, spans={}, quantize=2, steps={}), length=61, conf=8)])\n", + "\tp_gauss: QickPulse(waveforms=[Waveform(name='p_gauss_w0', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=32766, spans={}, quantize=1, steps={}), length=122, conf=8)])\n", + "\tp_const: QickPulse(waveforms=[Waveform(name='p_const_w0', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=32766, spans={}, quantize=1, steps={}), length=QickRawParam(par='length', start=92, spans={}, quantize=1, steps={}), conf=9)])\n", + "\tp_flattop_90: QickPulse(waveforms=[Waveform(name='p_flattop_90_w0', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=1073741824, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=32766, spans={}, quantize=2, steps={}), length=61, conf=8), Waveform(name='p_flattop_90_w1', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=1073741824, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=16383, spans={}, quantize=1, steps={}), length=QickRawParam(par='length', start=61, spans={}, quantize=1, steps={}), conf=9), Waveform(name='p_flattop_90_w2', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=1073741824, spans={}, quantize=1, steps={}), env=61, gain=QickRawParam(par='gain', start=32766, spans={}, quantize=2, steps={}), length=61, conf=8)])\n", + "\tmy_ro: QickPulse(waveforms=[Waveform(name='my_ro_w0', freq=QickRawParam(par='freq', start=-873813332, spans={}, quantize=-4, steps={}), phase=0, env=0, gain=0, length=3, conf=520)])\n", + "expanded ASM:\n", + "\t NOP \n", + "\t REG_WR s12 imm #0 \n", + "\t WPORT_WR p3 wmem [&8] @0 \n", + "\t TIME #614 inc_ref \n", + "\t REG_WR r0 imm #0 \n", + "\treps:\n", + "\t DPORT_WR p0 imm 1 @123 \n", + "\t TRIG p0 set @123 \n", + "\t TRIG p7 set @123 \n", + "\t DPORT_WR p0 imm 0 @133 \n", + "\t TRIG p0 clr @133 \n", + "\t TRIG p7 clr @133 \n", + "\t WPORT_WR p0 wmem [&0] @0 \n", + "\t WPORT_WR p0 wmem [&1] @0 \n", + "\t WPORT_WR p0 wmem [&2] @0 \n", + "\t WPORT_WR p0 wmem [&3] @246 \n", + "\t WPORT_WR p0 wmem [&4] @492 \n", + "\t WPORT_WR p0 wmem [&5] @737 \n", + "\t WPORT_WR p0 wmem [&6] @737 \n", + "\t WPORT_WR p0 wmem [&7] @737 \n", + "\t WPORT_WR p0 wmem [&3] @983 \n", + "\t WAIT @1351 time \n", + "\t TIME #1658 inc_ref \n", + "\t REG_WR s12 op -op(s12 + #1) \n", + "\t TEST -op(r0 - #0) \n", + "\t JUMP reps -if(NZ) -wr(r0 op) -op(r0 + #1) \n", + "\t JUMP HERE \n" + ] + } + ], + "source": [ + "print(prog)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Explanation:** This prints the compiled program in three sections:\n", + "1. **macros:** High-level operations (pulse definitions, loops, triggers)\n", + "2. **registers:** Allocated data registers\n", + "3. **pulses:** Defined waveforms with their parameters\n", + "4. **expanded ASM:** The actual assembly code that runs on the tProc\n", + "\n", + "Understanding this output becomes important when debugging complex sequences." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. Summary\n", + "\n", + "You have learned:\n", + "- The structure of a tProc v2 program (`_initialize` vs `_body`)\n", + "- How to define and play pulses of different styles (const, arb, flat_top)\n", + "- How to trigger readout and acquire IQ data\n", + "- How to inspect the generated assembly code\n", + "\n", + "**Next steps:** Proceed to [``02_Parameter_Sweeps.ipynb``](./02_Parameter_Sweeps.ipynb) to learn how to automate parameter variation and create 2D scans." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/source/tutorials/02_Parameter_Sweeps.ipynb b/docs/source/tutorials/02_Parameter_Sweeps.ipynb new file mode 100644 index 000000000..8d441b892 --- /dev/null +++ b/docs/source/tutorials/02_Parameter_Sweeps.ipynb @@ -0,0 +1,574 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 02 - Parameter Sweeps with tProc v2\n", + "\n", + "**Objective:** Learn how to automate parameter variation (sweeps) to create 1D and 2D scans, and understand how to retrieve the actual swept values." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%pybind11/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Standard imports\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import logging\n", + "\n", + "from qick import *\n", + "from qick.asm_v2 import AveragerProgramV2, QickSweep1D, QickSpan\n", + "\n", + "# Setup logging\n", + "logging.basicConfig(level=logging.INFO, format='%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s')\n", + "logging.getLogger(\"qick_processor\").setLevel(logging.WARNING)\n", + "\n", + "# Connect to the board (adjust the path to your firmware)\n", + "BITSTREAM_PATH = 'qick_216.bit'#'/path/to/your/firmware.bit' # <--- CHANGE THIS\n", + "soc = QickSoc(BITSTREAM_PATH)\n", + "soccfg = soc\n", + "\n", + "# Define hardware channels\n", + "GEN_CH = 0\n", + "RO_CH = 0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Understanding Sweeps\n", + "\n", + "In QICK, a **sweep** is an automatic variation of a parameter across multiple experiment shots. The tProc handles the looping internally, eliminating Python-to-FPGA communication latency.\n", + "\n", + "Key components:\n", + "- **`add_loop(name, steps)`** - Defines a loop that will run `steps` times\n", + "- **`QickSweep1D(loop_name, start, stop)`** - Creates a linear sweep from `start` to `stop` over the loop iterations\n", + "- **`get_pulse_param(pulse_name, param, as_array=True)`** - Retrieves the actual swept values (after hardware quantization)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. A Simple 1D Sweep\n", + "\n", + "Let's sweep the phase of a flat-top pulse from -360° to 720° while also sweeping the gain from 0 to 1." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b8d194b06e364eaebdc426464fc03e87", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/10 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Swept phase values (degrees): [-360. -90. 180. 450. 720.]\n", + "Swept gain values: [0. 0.24995422 0.49990844 0.74986266 0.99981688]\n" + ] + } + ], + "source": [ + "class SimpleSweepProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " \n", + " self.declare_gen(ch=gen_ch, nqz=1)\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'])\n", + "\n", + " # Define the loop that controls our sweep\n", + " self.add_loop(\"my_sweep\", self.cfg[\"steps\"])\n", + "\n", + " # Define a Gaussian envelope for pulse shaping\n", + " self.add_gauss(ch=gen_ch, name=\"ramp\", \n", + " sigma=cfg['ramp_len']/10, \n", + " length=cfg['ramp_len'], \n", + " even_length=True)\n", + " \n", + " # Define the pulse with swept parameters\n", + " self.add_pulse(ch=gen_ch, name=\"swept_pulse\", \n", + " style=\"flat_top\", \n", + " envelope=\"ramp\", \n", + " freq=cfg['freq'], \n", + " length=cfg['flat_len'],\n", + " phase=QickSweep1D(\"my_sweep\", -360, 720), # Sweep from -360° to 720°\n", + " gain=QickSweep1D(\"my_sweep\", 0.0, 1.0) # Sweep gain from 0 to 1\n", + " )\n", + "\n", + " # Configure readout\n", + " self.add_readoutconfig(ch=ro_ch, name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=gen_ch)\n", + " self.send_readoutconfig(ch=ro_ch, name=\"my_ro\", t=0)\n", + " \n", + " def _body(self, cfg):\n", + " self.pulse(ch=cfg['gen_ch'], name=\"swept_pulse\", t=0)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'])\n", + "\n", + "# Configuration\n", + "config = {\n", + " 'steps': 5, # Number of sweep points\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 100, # MHz\n", + " 'trig_time': 0.25, # µs\n", + " 'ro_len': 0.55, # µs\n", + " 'flat_len': 0.05, # µs (flat segment duration)\n", + " 'ramp_len': 0.2 # µs (ramp duration)\n", + "}\n", + "\n", + "# Run the sweep\n", + "prog = SimpleSweepProgram(soccfg, reps=1, final_delay=0.5, cfg=config)\n", + "iq_data = prog.acquire_decimated(soc, rounds=10)\n", + "time_axis = prog.get_time_axis(ro_index=0)\n", + "\n", + "# Plot magnitude for each sweep step\n", + "plt.figure(figsize=(10, 6))\n", + "for i, iq_point in enumerate(iq_data[0]):\n", + " plt.plot(time_axis, np.abs(iq_point.dot([1,1j])), label=f\"Step {i}\")\n", + "plt.legend()\n", + "plt.xlabel('Time (µs)')\n", + "plt.ylabel('Magnitude (a.u.)')\n", + "plt.title('1D Sweep: Phase from -360° to 720°, Gain from 0 to 1')\n", + "plt.grid(True)\n", + "plt.show()\n", + "\n", + "# Retrieve the actual swept values\n", + "phases = prog.get_pulse_param('swept_pulse', 'phase', as_array=True)\n", + "gains = prog.get_pulse_param('swept_pulse', 'gain', as_array=True)\n", + "print(f\"Swept phase values (degrees): {phases}\")\n", + "print(f\"Swept gain values: {gains}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Explanation:**\n", + "- `add_loop(\"my_sweep\", steps)` creates a loop. Any parameter wrapped in `QickSweep1D()` will vary across this loop.\n", + "- The tProc automatically:\n", + " 1. Updates the waveform parameters for each step\n", + " 2. Executes the `_body()` code\n", + " 3. Loops until all steps are complete\n", + "- `get_pulse_param()` returns the **actual** values after quantization, which may differ slightly from the requested values due to hardware precision limits." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. 2D Sweeps with Nested Loops\n", + "\n", + "For multi-dimensional scans, we can nest loops. The order of `add_loop()` calls determines the nesting order (first declared is outermost)." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "c53fda1a2e7b4dbfbeba4d45abd80a29", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/500000 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "class LengthSweepProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " \n", + " self.declare_gen(ch=gen_ch, nqz=1)\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'])\n", + "\n", + " self.add_loop(\"length_sweep\", self.cfg[\"steps\"])\n", + "\n", + " # Gaussian envelope (fixed parameters)\n", + " self.add_gauss(ch=gen_ch, name=\"ramp\", \n", + " sigma=cfg['ramp_len']/10, \n", + " length=cfg['ramp_len'], \n", + " even_length=True)\n", + " \n", + " # Flat-top pulse with swept length\n", + " self.add_pulse(ch=gen_ch, name=\"len_pulse\", \n", + " style=\"flat_top\", \n", + " envelope=\"ramp\", \n", + " freq=cfg['freq'], \n", + " length=QickSweep1D(\"length_sweep\", 0.05, 0.15), # Sweep from 50ns to 150ns\n", + " phase=0,\n", + " gain=cfg['gain']\n", + " )\n", + "\n", + " self.add_readoutconfig(ch=ro_ch, name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=gen_ch)\n", + " self.send_readoutconfig(ch=ro_ch, name=\"my_ro\", t=0)\n", + " \n", + " def _body(self, cfg):\n", + " self.pulse(ch=cfg['gen_ch'], name=\"len_pulse\", t=0)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'])\n", + "\n", + "# Configuration\n", + "config_len = {\n", + " 'steps': 5,\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500,\n", + " 'trig_time': 0.25,\n", + " 'ro_len': 0.5,\n", + " 'ramp_len': 0.1,\n", + " 'gain': 1.0\n", + "}\n", + "\n", + "# Run the length sweep\n", + "prog = LengthSweepProgram(soccfg, reps=1, final_delay=0.5, cfg=config_len)\n", + "iq_data = prog.acquire_decimated(soc, rounds=10)\n", + "time_axis = prog.get_time_axis(ro_index=0)\n", + "\n", + "# Get the actual length values\n", + "lengths = prog.get_pulse_param('len_pulse', 'length', as_array=True)\n", + "total_lengths = prog.get_pulse_param('len_pulse', 'total_length', as_array=True)\n", + "print(f\"Flat segment lengths (µs): {lengths}\")\n", + "print(f\"Total pulse lengths (µs): {total_lengths}\")\n", + "\n", + "# Plot results\n", + "plt.figure(figsize=(10, 6))\n", + "for i, iq_point in enumerate(iq_data[0]):\n", + " plt.plot(time_axis, np.abs(iq_point.dot([1,1j])), label=f\"Length = {lengths[i]:.3f} µs\")\n", + "plt.legend()\n", + "plt.xlabel('Time (µs)')\n", + "plt.ylabel('Magnitude (a.u.)')\n", + "plt.title('Sweeping Pulse Length')\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note on pulse lengths:**\n", + "- `length` refers to the flat segment duration (for flat-top pulses)\n", + "- `total_length` includes the rise and fall times\n", + "- Both can be swept independently" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. Inspecting Sweep Parameters\n", + "\n", + "You can list all available parameters for a pulse and retrieve their values." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Available parameters for 'len_pulse':\n", + "['length', 'freq', 'gain', 'phase', 'total_length']\n", + "\n", + "Swept values:\n", + " length: [0.05045573 0.07486979 0.09928385 0.12369792 0.14811198]\n", + " total_length: [0.15136719 0.17578125 0.20019531 0.22460938 0.24902344]\n", + " gain: 1.0\n", + " phase: 0.0\n", + " freq: 499.99999923706054\n" + ] + } + ], + "source": [ + "# List all parameters for the pulse\n", + "print(\"Available parameters for 'len_pulse':\")\n", + "print(prog.list_pulse_params('len_pulse'))\n", + "\n", + "# Get all swept values as a dictionary\n", + "# This is useful for saving experiment metadata\n", + "swept_values = {}\n", + "for param in ['length', 'total_length', 'gain', 'phase', 'freq']:\n", + " try:\n", + " swept_values[param] = prog.get_pulse_param('len_pulse', param, as_array=True)\n", + " except:\n", + " pass # Parameter not swept or not available\n", + "\n", + "print(\"\\nSwept values:\")\n", + "for param, values in swept_values.items():\n", + " print(f\" {param}: {values}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 7. Summary\n", + "\n", + "You have learned:\n", + "- How to create 1D sweeps using `add_loop()` and `QickSweep1D`\n", + "- How to create 2D sweeps using nested loops and `QickSpan`\n", + "- How to sweep pulse lengths and other parameters\n", + "- How to retrieve the actual swept values using `get_pulse_param()`\n", + "\n", + "**Key concepts:**\n", + "- Sweeps are executed entirely on the tProc, eliminating Python-FPGA latency\n", + "- Loop order determines the data shape (first declared = outermost)\n", + "- `QickSpan` allows building complex sweeps from simple components\n", + "- Always use `get_pulse_param()` to get the actual quantized values for accurate analysis\n", + "\n", + "**Next steps:** Proceed to [`03_Advanced_Timing.ipynb`](./03_Advanced_Timing.ipynb) to learn about timeline management, `delay` vs `wait`, and avoiding timing pitfalls." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/source/tutorials/03_Advanced_Timing.ipynb b/docs/source/tutorials/03_Advanced_Timing.ipynb new file mode 100644 index 000000000..f878ba3f6 --- /dev/null +++ b/docs/source/tutorials/03_Advanced_Timing.ipynb @@ -0,0 +1,616 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 03 - Advanced Timing with tProc v2\n", + "\n", + "**Objective:** Understand the critical differences between `delay()`, `wait()`, `delay_auto()`, and `wait_auto()`. Learn how to manage the timeline correctly to avoid pulse collisions and timing errors." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%pybind11/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Standard imports\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import logging\n", + "\n", + "from qick import *\n", + "from qick.asm_v2 import AveragerProgramV2, QickSweep1D\n", + "\n", + "# Setup logging\n", + "logging.basicConfig(level=logging.INFO, format='%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s')\n", + "logging.getLogger(\"qick_processor\").setLevel(logging.WARNING)\n", + "\n", + "# Connect to the board (adjust the path to your firmware)\n", + "BITSTREAM_PATH = 'qick_216.bit'#'/path/to/your/firmware.bit' # <--- CHANGE THIS\n", + "soc = QickSoc(BITSTREAM_PATH)\n", + "soccfg = soc\n", + "\n", + "# Define hardware channels\n", + "GEN_CH = 0\n", + "RO_CH = 0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Understanding the Timeline\n", + "\n", + "In tProc v2, all timed instructions (pulses, triggers, delays) are scheduled on a common timeline. The tProc maintains a **reference time** that advances as instructions are executed.\n", + "\n", + "**Key concepts:**\n", + "- **Absolute time:** The actual time from the start of the shot\n", + "- **Reference time:** The tProc's internal clock, which determines when the next instruction will execute\n", + "- **Scheduled time:** The time you specify for a pulse or trigger (e.g., `t=0.5`)\n", + "\n", + "**The four timing commands:**\n", + "\n", + "| Command | What it does | When to use |\n", + "| :--- | :--- | :--- |\n", + "| `delay(t)` | Adds `t` to the reference time | When you know exactly how long to wait |\n", + "| `wait(t)` | Waits until the reference time reaches `t` | When you need to wait for a specific absolute time |\n", + "| `delay_auto(t, gens=True, ros=True)` | Adds `t` PLUS the time needed to complete all pending gens/ROs | Safe way to ensure everything finishes |\n", + "| `wait_auto(t, gens=False, ros=True)` | Waits until reference time reaches `t` OR pending operations finish | Similar to v1's `sync_all()` |" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Basic Timing: `delay()` vs `wait()`\n", + "\n", + "The simplest timing commands are `delay()` and `wait()`. They work with absolute and relative timing." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "WARNING [asm_v2.py:998] warning: pulse time 0 appears to conflict with previous pulse ending at ?\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== Using DELAY ===\n", + " NOP \n", + " REG_WR s12 imm #0 \n", + " WPORT_WR p3 wmem [&1] @0 \n", + " TIME #614 inc_ref \n", + " REG_WR r0 imm #0 \n", + "reps:\n", + " DPORT_WR p0 imm 1 @307 \n", + " TRIG p0 set @307 \n", + " DPORT_WR p0 imm 0 @317 \n", + " TRIG p0 clr @317 \n", + " WPORT_WR p0 wmem [&0] @0 \n", + " TIME #492 inc_ref \n", + " WPORT_WR p0 wmem [&0] @0 \n", + " WAIT @1043 time \n", + " TIME #1350 inc_ref \n", + " REG_WR s12 op -op(s12 + #1) \n", + " TEST -op(r0 - #0) \n", + " JUMP reps -if(NZ) -wr(r0 op) -op(r0 + #1) \n", + " JUMP HERE \n", + "\n", + "\n", + "=== Using WAIT ===\n", + " NOP \n", + " REG_WR s12 imm #0 \n", + " WPORT_WR p3 wmem [&1] @0 \n", + " TIME #614 inc_ref \n", + " REG_WR r0 imm #0 \n", + "reps:\n", + " DPORT_WR p0 imm 1 @307 \n", + " TRIG p0 set @307 \n", + " DPORT_WR p0 imm 0 @317 \n", + " TRIG p0 clr @317 \n", + " WPORT_WR p0 wmem [&0] @0 \n", + " WAIT @492 time \n", + " WPORT_WR p0 wmem [&0] @0 \n", + " WAIT @1535 time \n", + " TIME #1842 inc_ref \n", + " REG_WR s12 op -op(s12 + #1) \n", + " TEST -op(r0 - #0) \n", + " JUMP reps -if(NZ) -wr(r0 op) -op(r0 + #1) \n", + " JUMP HERE \n", + "\n" + ] + } + ], + "source": [ + "class TimingExampleProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " \n", + " self.declare_gen(ch=gen_ch, nqz=1)\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'])\n", + "\n", + " # Define a constant pulse\n", + " self.add_pulse(ch=gen_ch, name=\"test_pulse\", \n", + " style=\"const\", \n", + " freq=cfg['freq'], \n", + " length=cfg['pulse_len'],\n", + " phase=0, gain=1.0)\n", + "\n", + " self.add_readoutconfig(ch=ro_ch, name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=gen_ch)\n", + " self.send_readoutconfig(ch=ro_ch, name=\"my_ro\", t=0)\n", + " \n", + " def _body(self, cfg):\n", + " # Trigger readout at t=0.5 µs\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=0.5)\n", + " \n", + " # First pulse at t=0\n", + " self.pulse(ch=cfg['gen_ch'], name=\"test_pulse\", t=0)\n", + " \n", + " if cfg['use_wait']:\n", + " # Using wait: pause until reference time reaches 0.8 µs\n", + " self.wait(0.8)\n", + " else:\n", + " # Using delay: add 0.8 µs to reference time\n", + " self.delay(0.8)\n", + " \n", + " # Second pulse - when does it play?\n", + " self.pulse(ch=cfg['gen_ch'], name=\"test_pulse\", t=0)\n", + "\n", + "# Compare delay vs wait\n", + "config = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500,\n", + " 'pulse_len': 0.1,\n", + " 'ro_len': 2.0,\n", + " 'use_wait': False\n", + "}\n", + "\n", + "print(\"=== Using DELAY ===\")\n", + "prog = TimingExampleProgram(soccfg, reps=1, final_delay=0.5, cfg=config)\n", + "\n", + "# Get the compiled program as text to inspect the timing\n", + "print(prog.asm())\n", + "\n", + "print(\"\\n=== Using WAIT ===\")\n", + "config['use_wait'] = True\n", + "prog = TimingExampleProgram(soccfg, reps=1, final_delay=0.5, cfg=config)\n", + "print(prog.asm())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Key difference:**\n", + "- `delay(0.8)` adds 0.8 µs to the reference time, so the second pulse plays 0.8 µs after the first pulse ends\n", + "- `wait(0.8)` pauses until the reference time reaches exactly 0.8 µs (absolute time from shot start)\n", + "\n", + "**Rule of thumb:** Use `delay()` for relative timing between pulses. Use `wait()` for absolute timing or when waiting for a specific absolute time." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Auto-Timing: `delay_auto()` and `wait_auto()`\n", + "\n", + "The `_auto` variants automatically account for pending operations (pulses that haven't finished, readouts that are still acquiring). This is safer when you're not sure how long previous operations will take." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " NOP \n", + " REG_WR s12 imm #0 \n", + " WPORT_WR p3 wmem [&2] @0 \n", + " TIME #614 inc_ref \n", + " REG_WR r0 imm #0 \n", + "reps:\n", + " WPORT_WR p0 wmem [&0] @0 \n", + " TIME #184 inc_ref \n", + " WPORT_WR p0 wmem [&1] @0 \n", + " DPORT_WR p0 imm 1 @492 \n", + " TRIG p0 set @492 \n", + " DPORT_WR p0 imm 0 @502 \n", + " TRIG p0 clr @502 \n", + " WAIT @1414 time \n", + " TIME #1721 inc_ref \n", + " REG_WR s12 op -op(s12 + #1) \n", + " TEST -op(r0 - #0) \n", + " JUMP reps -if(NZ) -wr(r0 op) -op(r0 + #1) \n", + " JUMP HERE \n", + "\n" + ] + } + ], + "source": [ + "class AutoTimingProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " \n", + " self.declare_gen(ch=gen_ch, nqz=1)\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'])\n", + "\n", + " # Define pulses with swept lengths\n", + " self.add_pulse(ch=gen_ch, name=\"pulse_a\", \n", + " style=\"const\", \n", + " freq=cfg['freq'], \n", + " length=cfg['len_a'],\n", + " phase=0, gain=1.0)\n", + " \n", + " self.add_pulse(ch=gen_ch, name=\"pulse_b\", \n", + " style=\"const\", \n", + " freq=cfg['freq'], \n", + " length=cfg['len_b'],\n", + " phase=0, gain=1.0)\n", + "\n", + " self.add_readoutconfig(ch=ro_ch, name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=gen_ch)\n", + " self.send_readoutconfig(ch=ro_ch, name=\"my_ro\", t=0)\n", + " \n", + " def _body(self, cfg):\n", + " # Play first pulse at t=0\n", + " self.pulse(ch=cfg['gen_ch'], name=\"pulse_a\", t=0)\n", + " \n", + " # Auto-delay: wait for pulse_a to finish, then add extra time\n", + " # ros=False means don't wait for readout (which hasn't started yet)\n", + " self.delay_auto(cfg['gap'], ros=False)\n", + " \n", + " # Play second pulse\n", + " self.pulse(ch=cfg['gen_ch'], name=\"pulse_b\", t=0)\n", + " \n", + " # Trigger readout after both pulses\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'])\n", + "\n", + "# Demo: pulse lengths vary, but the gap between them stays constant\n", + "config_auto = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500,\n", + " 'len_a': 0.2, # µs\n", + " 'len_b': 0.3, # µs (different length!)\n", + " 'gap': 0.1, # µs gap between pulses\n", + " 'trig_time': 0.8, # µs\n", + " 'ro_len': 1.5 # µs\n", + "}\n", + "\n", + "prog = AutoTimingProgram(soccfg, reps=1, final_delay=0.5, cfg=config_auto)\n", + "\n", + "# Print the compiled program to see the generated assembly\n", + "print(prog.asm())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Why `delay_auto()` is powerful:**\n", + "- It automatically calculates when pulse A ends\n", + "- Then schedules pulse B to start at `(end_of_pulse_A + gap)`\n", + "- This works even if pulse lengths change (e.g., in a sweep)\n", + "\n", + "**Parameters:**\n", + "- `gens=True/False`: Whether to wait for generator operations (pulses)\n", + "- `ros=True/False`: Whether to wait for readout operations\n", + "- Default for `delay_auto()`: `gens=True, ros=True`\n", + "- Default for `wait_auto()`: `gens=False, ros=True` (like v1's `sync_all`)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Common Pitfall: Pulse Collisions\n", + "\n", + "If you schedule a pulse before the previous one finishes, the tProc will give you a warning (if you have logging enabled) but will still execute. This can cause unexpected results." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "WARNING [asm_v2.py:998] warning: pulse time 0.3 appears to conflict with previous pulse ending at ?\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Program with potential pulse collision:\n", + " NOP \n", + " REG_WR s12 imm #0 \n", + " WPORT_WR p3 wmem [&1] @0 \n", + " TIME #614 inc_ref \n", + " REG_WR r0 imm #0 \n", + "reps:\n", + " WPORT_WR p0 wmem [&0] @0 \n", + " WPORT_WR p0 wmem [&0] @184 \n", + " DPORT_WR p0 imm 1 @369 \n", + " TRIG p0 set @369 \n", + " DPORT_WR p0 imm 0 @379 \n", + " TRIG p0 clr @379 \n", + " WAIT @983 time \n", + " TIME #1290 inc_ref \n", + " REG_WR s12 op -op(s12 + #1) \n", + " TEST -op(r0 - #0) \n", + " JUMP reps -if(NZ) -wr(r0 op) -op(r0 + #1) \n", + " JUMP HERE \n", + "\n", + "\n", + "Note: The second pulse is scheduled before the first finishes!\n" + ] + } + ], + "source": [ + "class CollisionProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + "\n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"long_pulse\", \n", + " style=\"const\", \n", + " freq=cfg['freq'], length=0.5, phase=0, gain=1.0)\n", + "\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=cfg['gen_ch'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", t=0)\n", + " \n", + " def _body(self, cfg):\n", + " # First pulse at t=0\n", + " self.pulse(ch=cfg['gen_ch'], name=\"long_pulse\", t=0)\n", + " \n", + " # This pulse is scheduled while the first is still playing!\n", + " # The tProc will issue a warning.\n", + " self.pulse(ch=cfg['gen_ch'], name=\"long_pulse\", t=0.3)\n", + " \n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=0.6)\n", + "\n", + "config_collision = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500,\n", + " 'ro_len': 1.0\n", + "}\n", + "\n", + "prog = CollisionProgram(soccfg, reps=1, final_delay=0.5, cfg=config_collision)\n", + "print(\"Program with potential pulse collision:\")\n", + "print(prog.asm())\n", + "print(\"\\nNote: The second pulse is scheduled before the first finishes!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**How to fix:** Use `delay_auto()` to ensure proper spacing.\n", + "\n", + "```python\n", + "# Instead of:\n", + "self.pulse(ch=gen_ch, name=\"long_pulse\", t=0)\n", + "self.pulse(ch=gen_ch, name=\"long_pulse\", t=0.3) # Collision!\n", + "\n", + "# Do this:\n", + "self.pulse(ch=gen_ch, name=\"long_pulse\", t=0)\n", + "self.delay_auto(0.1) # Wait for pulse to finish, then add 0.1 µs\n", + "self.pulse(ch=gen_ch, name=\"long_pulse\", t=0) # Safely scheduled\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. Sweeping Delays\n", + "\n", + "You can sweep delay times just like pulse parameters." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Program with swept delay:\n", + " NOP \n", + " REG_WR r2 imm #61 \n", + " REG_WR r3 imm #1167 \n", + " REG_WR s12 imm #0 \n", + " WPORT_WR p3 wmem [&1] @0 \n", + " TIME #614 inc_ref \n", + " REG_WR r0 imm #0 \n", + "reps:\n", + " REG_WR r1 imm #0 \n", + "delay_sweep:\n", + " DPORT_WR p0 imm 1 @307 \n", + " TRIG p0 set @307 \n", + " DPORT_WR p0 imm 0 @317 \n", + " TRIG p0 clr @317 \n", + " WPORT_WR p0 wmem [&0] @0 \n", + " TIME inc_ref r2 \n", + " WPORT_WR p0 wmem [&0] @0 \n", + " WAIT @860 time \n", + " TIME inc_ref r3 \n", + " REG_WR s12 op -op(s12 + #1) \n", + " REG_WR r2 op -op(r2 + #61) \n", + " REG_WR r3 op -op(r3 + #-61) \n", + " TEST -op(r1 - #4) \n", + " JUMP delay_sweep -if(NZ) -wr(r1 op) -op(r1 + #1) \n", + " REG_WR r2 op -op(r2 + #-305) \n", + " REG_WR r3 op -op(r3 + #305) \n", + " TEST -op(r0 - #0) \n", + " JUMP reps -if(NZ) -wr(r0 op) -op(r0 + #1) \n", + " JUMP HERE \n", + "\n", + "\n", + "Note: The tProc will automatically handle the varying delay times.\n" + ] + } + ], + "source": [ + "class DelaySweepProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + "\n", + " self.add_loop(\"delay_sweep\", self.cfg[\"steps\"])\n", + "\n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"test_pulse\", \n", + " style=\"const\", \n", + " freq=cfg['freq'], length=0.1,\n", + " phase=0, gain=1.0)\n", + "\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=cfg['gen_ch'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", t=0)\n", + " \n", + " def _body(self, cfg):\n", + " # Trigger readout at fixed time\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=0.5)\n", + " \n", + " # First pulse at t=0\n", + " self.pulse(ch=cfg['gen_ch'], name=\"test_pulse\", t=0)\n", + " \n", + " # Sweep the delay between pulses\n", + " self.delay(QickSweep1D(\"delay_sweep\", 0.1, 0.5))\n", + " \n", + " # Second pulse\n", + " self.pulse(ch=cfg['gen_ch'], name=\"test_pulse\", t=0)\n", + "\n", + "config_delay_sweep = {\n", + " 'steps': 5,\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500,\n", + " 'ro_len': 1.0\n", + "}\n", + "\n", + "prog = DelaySweepProgram(soccfg, reps=1, final_delay=0.5, cfg=config_delay_sweep)\n", + "\n", + "# Show that the program compiles with swept delays\n", + "print(\"Program with swept delay:\")\n", + "print(prog.asm())\n", + "print(\"\\nNote: The tProc will automatically handle the varying delay times.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 7. Summary\n", + "\n", + "You have learned:\n", + "- The difference between `delay()` (relative) and `wait()` (absolute)\n", + "- How `delay_auto()` and `wait_auto()` automatically account for pending operations\n", + "- How to avoid pulse collisions by using proper timing commands\n", + "- How to sweep delay times\n", + "- How to inspect the generated assembly code using `asm()` to verify timing\n", + "\n", + "**Best practices:**\n", + "1. **Use `delay_auto()` when you want to wait for pulses to finish** - It's safer and works with swept lengths\n", + "2. **Use `wait()` for absolute timing** - When you need to hit an exact absolute time\n", + "3. **Use `delay()` for simple relative timing** - When you know exactly how long to wait\n", + "4. **Always check for pulse collisions** - Use `print(prog.asm())` to inspect the generated code\n", + "5. **Use tags to identify instructions** - Tags help with debugging and retrieving parameters\n", + "\n", + "**Next steps:** Proceed to [`04_Real_Time_Feedback.ipynb`](./04_Real_Time_Feedback.ipynb) to learn how to read measurement results and make decisions on the tProc in real-time." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/source/tutorials/04_Real_Time_Feedback.ipynb b/docs/source/tutorials/04_Real_Time_Feedback.ipynb new file mode 100644 index 000000000..5c8781d00 --- /dev/null +++ b/docs/source/tutorials/04_Real_Time_Feedback.ipynb @@ -0,0 +1,608 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 04 - Real-Time Feedback with tProc v2\n", + "\n", + "**Objective:** Learn how to read measurement results directly on the tProc and make real-time decisions (conditional pulses, active reset, adaptive measurements)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%pybind11/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Standard imports\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import logging\n", + "\n", + "from qick import *\n", + "from qick.asm_v2 import AveragerProgramV2, QickSweep1D\n", + "\n", + "# Setup logging\n", + "logging.basicConfig(level=logging.INFO, format='%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s')\n", + "logging.getLogger(\"qick_processor\").setLevel(logging.WARNING)\n", + "\n", + "# Connect to the board (adjust the path to your firmware)\n", + "BITSTREAM_PATH = 'qick_216.bit'#'/path/to/your/firmware.bit' # <--- CHANGE THIS\n", + "soc = QickSoc(BITSTREAM_PATH)\n", + "soccfg = soc\n", + "\n", + "# Define hardware channels\n", + "GEN_CH = 0\n", + "RO_CH = 0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Understanding tProc Feedback\n", + "\n", + "The tProc can read accumulated IQ values from the readout module and use them to make decisions in real-time. This enables:\n", + "- Conditional pulse sequences (e.g., play a second pulse only if a measurement exceeds a threshold)\n", + "- Active reset (play a pulse conditioned on measurement outcome)\n", + "- Adaptive measurements (change experiment parameters based on results)\n", + "\n", + "**Key commands:**\n", + "- `read_input(ro_ch)` - Reads the accumulated IQ value from a readout channel into registers `s_port_l` (I) and `s_port_h` (Q)\n", + "- `cond_jump(label, condition)` - Conditional jump based on register values\n", + "- `read_and_jump()` - Convenience method that combines both\n", + "\n", + "**Important:** After triggering a readout, you must wait for it to complete before reading the value. This requires tuning the `read_wait` parameter." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Measuring Readout Latency\n", + "\n", + "Before using feedback, you need to determine the correct `read_wait` time. This is the delay between triggering a readout and when the accumulated value is available to the tProc." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Buffered I/Q: (-0, 0)\n", + "Feedback I/Q: (12, 5)\n", + "\n", + "✗ Feedback and buffered readouts do NOT match! Increase 'read_wait'.\n" + ] + } + ], + "source": [ + "class LatencyMeasurementProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " \n", + " self.declare_gen(ch=gen_ch, nqz=1)\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'])\n", + "\n", + " # Define a constant test pulse\n", + " self.add_pulse(ch=gen_ch, name=\"test_pulse\", \n", + " style=\"const\", \n", + " freq=cfg['freq'], \n", + " length=cfg['pulse_len'],\n", + " phase=cfg['pulse_phase'],\n", + " gain=cfg['gain'])\n", + "\n", + " # Configure readout\n", + " self.add_readoutconfig(ch=ro_ch, name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=gen_ch, \n", + " phase=cfg['ro_phase'])\n", + " self.send_readoutconfig(ch=ro_ch, name=\"my_ro\", t=0)\n", + " \n", + " def _body(self, cfg):\n", + " # Play pulse\n", + " self.pulse(ch=cfg['gen_ch'], name=\"test_pulse\", t=0)\n", + " \n", + " # Trigger readout\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'])\n", + " \n", + " # Wait for readout to complete\n", + " self.wait_auto(cfg['read_wait'])\n", + " \n", + " # Read the accumulated I/Q value into tProc registers\n", + " self.read_input(ro_ch=cfg['ro_ch'])\n", + " \n", + " # Store the values to data memory for reading back from Python\n", + " self.write_dmem(addr=0, src='s_port_l') # I value (lower 32 bits)\n", + " self.write_dmem(addr=1, src='s_port_h') # Q value (upper 32 bits)\n", + "\n", + "# Configuration\n", + "config_latency = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500,\n", + " 'pulse_len': 0.025,\n", + " 'pulse_phase': 0,\n", + " 'ro_phase': 0,\n", + " 'gain': 1.0,\n", + " 'trig_time': 0.25,\n", + " 'ro_len': 0.1,\n", + " 'read_wait': 0.1 # This needs to be tuned\n", + "}\n", + "\n", + "# Run the measurement\n", + "prog = LatencyMeasurementProgram(soccfg, reps=100, final_delay=0.5, cfg=config_latency)\n", + "\n", + "# Acquire data - this also gives us the buffered readout values\n", + "iq_data = prog.acquire(soc, rounds=1, progress=False)\n", + "\n", + "# Get the feedback readout values from data memory\n", + "# read_mem returns a numpy array of int32 values\n", + "I_feedback = soc.read_mem(length=1, mem_sel='dmem', addr=0)[0]\n", + "Q_feedback = soc.read_mem(length=1, mem_sel='dmem', addr=1)[0]\n", + "\n", + "# Get the buffered readout values (from acquire())\n", + "# Shape is (1, 2) → (rounds, IQ)\n", + "I_buffered = iq_data[0][0, 0] * prog.cfg['ro_len'] # round 0, I\n", + "Q_buffered = iq_data[0][0, 1] * prog.cfg['ro_len'] # round 0, Q\n", + "\n", + "print(f\"Buffered I/Q: ({I_buffered:.0f}, {Q_buffered:.0f})\")\n", + "print(f\"Feedback I/Q: ({I_feedback}, {Q_feedback})\")\n", + "\n", + "if I_feedback == I_buffered and Q_feedback == Q_buffered:\n", + " print(\"\\n✓ Feedback and buffered readouts match! Latency is correct.\")\n", + "else:\n", + " print(\"\\n✗ Feedback and buffered readouts do NOT match! Increase 'read_wait'.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Explanation:**\n", + "- The buffered readout (from `acquire()`) is reliable and length-normalized\n", + "- The feedback readout (via `read_input()`) gives raw accumulated values\n", + "- If they don't match, increase `read_wait` until they do\n", + "- Once tuned, this `read_wait` value can be used for all feedback experiments" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Conditional Pulse: If-Then-Else on the tProc\n", + "\n", + "Now let's use feedback to conditionally play a second pulse based on the measurement result." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "5f8ea227444e4350bff98d3ec996e48b", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/10 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "class ConditionalPulseProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " \n", + " self.declare_gen(ch=gen_ch, nqz=1)\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'])\n", + "\n", + " self.add_loop(\"feedback_sweep\", self.cfg[\"steps\"])\n", + "\n", + " # Define pulses\n", + " self.add_pulse(ch=gen_ch, name=\"cond_pulse\", \n", + " style=\"const\", \n", + " freq=cfg['freq'], \n", + " length=cfg['pulse_len'],\n", + " phase=cfg['pulse_phase'],\n", + " gain=cfg['gain'])\n", + "\n", + " # Configure readout with phase rotation for optimal sensitivity\n", + " self.add_readoutconfig(ch=ro_ch, name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=gen_ch, \n", + " phase=cfg['ro_phase'])\n", + " self.send_readoutconfig(ch=ro_ch, name=\"my_ro\", t=0)\n", + " \n", + " def _body(self, cfg):\n", + " # First pulse and readout (the measurement)\n", + " self.pulse(ch=cfg['gen_ch'], name=\"cond_pulse\", t=0)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'])\n", + "\n", + " # Wait for readout to complete (tuned latency)\n", + " self.wait_auto(cfg['read_wait'])\n", + " self.delay_auto(cfg['read_wait'] + cfg['extra_delay'])\n", + "\n", + " # Second readout (for feedback decision)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'])\n", + "\n", + " # If I >= threshold, jump to 'SKIP_PULSE'\n", + " self.read_and_jump(ro_ch=cfg['ro_ch'], \n", + " component='I', \n", + " threshold=cfg['threshold'], \n", + " test='>=', \n", + " label='SKIP_PULSE')\n", + " \n", + " # --- This code is skipped if condition is true ---\n", + " # Second pulse (only played if I < threshold)\n", + " self.pulse(ch=cfg['gen_ch'], name=\"cond_pulse\", t=0, tag='conditional_pulse')\n", + " \n", + " # Label for conditional jump\n", + " self.label(\"SKIP_PULSE\")\n", + "\n", + "# Configuration\n", + "config_conditional = {\n", + " 'steps': 9,\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500,\n", + " 'trig_time': 0.25,\n", + " 'read_wait': 0.1, # Tuned from latency measurement\n", + " 'extra_delay': 0.2, # Extra safety margin\n", + " 'threshold': 0, # Threshold on I component\n", + " 'ro_len': 0.1,\n", + " 'pulse_len': 0.025,\n", + " 'pulse_phase': 0,\n", + " 'ro_phase': 0, # Optimize via rotation\n", + " 'gain': QickSweep1D(\"feedback_sweep\", -1.0, 1.0)\n", + "}\n", + "\n", + "# Run the experiment\n", + "prog = ConditionalPulseProgram(soccfg, reps=1, final_delay=0.5, cfg=config_conditional)\n", + "iq_data = prog.acquire_decimated(soc, rounds=10)\n", + "time_axis = prog.get_time_axis(ro_index=0)\n", + "\n", + "# Plot results for each sweep step\n", + "fig, axes = plt.subplots(1, 2, figsize=(14, 5))\n", + "\n", + "for i_read in range(2):\n", + " ax = axes[i_read]\n", + " for i_step, iq_point in enumerate(iq_data[0]):\n", + " ax.plot(time_axis, iq_point[i_read, :, 0], label=f\"Step {i_step}\")\n", + " ax.set_title(f\"Readout {i_read+1} - I Component\")\n", + " ax.set_xlabel(\"Time (µs)\")\n", + " ax.set_ylabel(\"Amplitude (a.u.)\")\n", + " ax.legend()\n", + " ax.grid(True)\n", + "\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Explanation:**\n", + "- The first readout measures the result\n", + "- If `I >= threshold`, the tProc jumps to `SKIP_PULSE`, skipping the second pulse\n", + "- If `I < threshold`, the second pulse is played\n", + "- This runs entirely on the tProc with no Python involvement\n", + "\n", + "**Note:** The threshold comparison uses raw (non-normalized) accumulated values. The same `read_wait` tuned from the latency measurement is critical here." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Active Reset\n", + "\n", + "A common feedback application is active reset: play a reset pulse conditioned on the qubit state." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Active reset program created successfully.\n", + "In practice, you would add a verification readout after the reset pulse.\n" + ] + } + ], + "source": [ + "class ActiveResetProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " \n", + " self.declare_gen(ch=gen_ch, nqz=1)\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'])\n", + "\n", + " # Measurement pulse\n", + " self.add_pulse(ch=gen_ch, name=\"measure_pulse\", \n", + " style=\"const\", \n", + " freq=cfg['freq'], \n", + " length=cfg['pulse_len'],\n", + " phase=0, gain=1.0)\n", + " \n", + " # Reset pulse (π pulse to bring qubit to ground)\n", + " self.add_pulse(ch=gen_ch, name=\"reset_pulse\", \n", + " style=\"const\", \n", + " freq=cfg['freq'], \n", + " length=cfg['reset_len'],\n", + " phase=0, gain=1.0)\n", + "\n", + " self.add_readoutconfig(ch=ro_ch, name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=gen_ch, \n", + " phase=cfg['ro_phase'])\n", + " self.send_readoutconfig(ch=ro_ch, name=\"my_ro\", t=0)\n", + " \n", + " def _body(self, cfg):\n", + " # Measurement\n", + " self.pulse(ch=cfg['gen_ch'], name=\"measure_pulse\", t=0)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'])\n", + "\n", + " self.wait_auto(cfg['read_wait'])\n", + " self.delay_auto(cfg['read_wait'] + cfg['extra_delay'])\n", + "\n", + " # If I >= threshold (qubit in excited state), play reset pulse\n", + " self.read_and_jump(ro_ch=cfg['ro_ch'], \n", + " component='I', \n", + " threshold=cfg['threshold'], \n", + " test='>=', \n", + " label='NO_RESET')\n", + " \n", + " self.pulse(ch=cfg['gen_ch'], name=\"reset_pulse\", t=0, tag='reset_pulse')\n", + " self.label(\"NO_RESET\")\n", + "\n", + "config_reset = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500,\n", + " 'trig_time': 0.25,\n", + " 'read_wait': 0.1,\n", + " 'extra_delay': 0.2,\n", + " 'threshold': 0,\n", + " 'ro_len': 0.1,\n", + " 'pulse_len': 0.025,\n", + " 'reset_len': 0.05,\n", + " 'ro_phase': 0\n", + "}\n", + "\n", + "prog = ActiveResetProgram(soccfg, reps=100, final_delay=0.5, cfg=config_reset)\n", + "\n", + "# In a real experiment, you would verify that the reset works by\n", + "# measuring the state after reset. This would require a second readout.\n", + "print(\"Active reset program created successfully.\")\n", + "print(\"In practice, you would add a verification readout after the reset pulse.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. Visualizing the Feedback Decision\n", + "\n", + "Let's examine how the threshold affects the conditional pulse decision." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "e65b9f1aa9834fa791658680ef6ea8a3", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/2000 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Conditional pulse played for 1003 out of 2000 steps\n", + "Trigger threshold crossed when I_first >= 2000\n" + ] + } + ], + "source": [ + "# Run a sweep with varying gain and observe when the conditional pulse triggers\n", + "config_conditional['steps'] = 2000\n", + "config_conditional['threshold'] = 2000 # Set a fixed threshold\n", + "\n", + "prog = ConditionalPulseProgram(soccfg, reps=1, final_delay=0.5, cfg=config_conditional)\n", + "\n", + "# Acquire data without decimation to get single-shot values\n", + "iq_data = prog.acquire(soc, rounds=1)\n", + "gains = prog.get_pulse_param('cond_pulse', 'gain', as_array=True)\n", + "\n", + "print(\"iq_data length:\", len(iq_data))\n", + "for i, d in enumerate(iq_data):\n", + " print(f\"iq_data[{i}] shape:\", d.shape)\n", + "# The shape: (reps, steps, readout_length, I/Q)\n", + "# For feedback, we care about the integrated value (sum over readout window)\n", + "# Shape: (readouts, steps, IQ)\n", + "# iq_data[0][readout, step, I/Q]\n", + "\n", + "I_first = iq_data[0][0, :, 0] * prog.cfg['ro_len'] # primer readout, I, todos los steps\n", + "I_second = iq_data[0][1, :, 0] * prog.cfg['ro_len'] # segundo readout, I, todos los steps\n", + "\n", + "plt.figure(figsize=(10, 6))\n", + "plt.plot(gains, I_first, 'o-', label='First readout (measurement)')\n", + "plt.plot(gains, I_second, 's-', label='Second readout (conditional)')\n", + "plt.axhline(y=config_conditional['threshold'], color='r', linestyle='--', \n", + " label=f'Threshold = {config_conditional[\"threshold\"]}')\n", + "plt.xlabel('Gain')\n", + "plt.ylabel('Integrated I (a.u.)')\n", + "plt.title('Feedback Decision: Conditional Pulse Trigger')\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.show()\n", + "\n", + "triggered = I_second > 0\n", + "print(f\"Conditional pulse played for {np.sum(triggered)} out of {len(gains)} steps\")\n", + "print(f\"Trigger threshold crossed when I_first >= {config_conditional['threshold']}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Observations:**\n", + "- The first readout (measurement) varies with gain as expected\n", + "- The second readout (conditional) is zero when the condition fails (pulse not played)\n", + "- The second readout has a signal only when the conditional pulse was actually played\n", + "- The threshold determines the decision boundary" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 7. Summary\n", + "\n", + "You have learned:\n", + "- How to measure and tune readout latency for reliable feedback\n", + "- How to read accumulated IQ values directly on the tProc using `read_input()`\n", + "- How to implement conditional pulses using `read_and_jump()`\n", + "- How to implement active reset for qubit state initialization\n", + "- How to verify that your feedback logic is working correctly\n", + "\n", + "**Key concepts:**\n", + "- `read_wait` must be tuned to match your hardware latency\n", + "- Feedback uses raw (non-normalized) accumulated values\n", + "- The tProc can make decisions in microseconds, enabling active reset and adaptive protocols\n", + "- Always verify feedback behavior with benchmark measurements\n", + "- Use `read_mem()` to retrieve values written to data memory\n", + "\n", + "**Next steps:** Proceed to [`05_Dynamic_Parameters_Subroutines.ipynb`](./05_Dynamic_Parameters_Subroutines.ipynb) to learn how to modify pulse parameters dynamically and use subroutines for code reuse." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/source/tutorials/05_Dynamic_Parameters_Subroutines.ipynb b/docs/source/tutorials/05_Dynamic_Parameters_Subroutines.ipynb new file mode 100644 index 000000000..43d718ee0 --- /dev/null +++ b/docs/source/tutorials/05_Dynamic_Parameters_Subroutines.ipynb @@ -0,0 +1,720 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 05 - Dynamic Parameters and Subroutines with tProc v2\n", + "\n", + "**Objective:** Learn how to modify pulse parameters dynamically in real-time (virtual-Z gates, phase updates) and use subroutines for efficient code reuse on the tProc." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%pybind11/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Standard imports\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import logging\n", + "\n", + "from qick import *\n", + "from qick.asm_v2 import AveragerProgramV2, AsmV2\n", + "\n", + "# Setup logging\n", + "logging.basicConfig(level=logging.INFO, format='%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s')\n", + "logging.getLogger(\"qick_processor\").setLevel(logging.WARNING)\n", + "\n", + "# Connect to the board (adjust the path to your firmware)\n", + "BITSTREAM_PATH = 'qick_216.bit'#'/path/to/your/firmware.bit' # <--- CHANGE THIS\n", + "soc = QickSoc(BITSTREAM_PATH)\n", + "soccfg = soc\n", + "\n", + "# Define hardware channels\n", + "GEN_CH = 0\n", + "RO_CH = 0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Understanding Dynamic Parameter Updates\n", + "\n", + "In tProc v2, pulse parameters are stored in **waveform memory**. Each pulse consists of one or more waveforms (for flat-top pulses: rise, flat, fall). You can:\n", + "- **Read** a waveform from memory into waveform registers\n", + "- **Modify** parameters in the registers (frequency, phase, gain, length)\n", + "- **Write** the modified waveform back to memory\n", + "\n", + "This allows you to change pulse properties on-the-fly without recompiling the program.\n", + "\n", + "**Key operations:**\n", + "- `read_wmem(name)` - Read a waveform into registers\n", + "- `write_wmem(name)` - Write registers back to waveform memory\n", + "- Waveform registers: `w_freq`, `w_phase`, `w_gain`, `w_length`, `w_env`, `w_conf`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Virtual-Z Gate: Updating Phase Dynamically\n", + "\n", + "A virtual-Z gate is a phase update applied to subsequent pulses without playing an actual pulse. This is essential for many quantum control sequences." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d05e3cb4906c48ea8659581ea582fd54", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/10 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "=== Virtual-Z Subroutine ASM ===\n", + " NOP \n", + " REG_WR s12 imm #0 \n", + " WPORT_WR p3 wmem [&3] @0 \n", + " TIME #614 inc_ref \n", + " REG_WR r0 imm #0 \n", + "reps:\n", + " DPORT_WR p0 imm 1 @154 \n", + " TRIG p0 set @154 \n", + " TRIG p7 set @154 \n", + " DPORT_WR p0 imm 0 @164 \n", + " TRIG p0 clr @164 \n", + " TRIG p7 clr @164 \n", + " WPORT_WR p0 wmem [&0] @0 \n", + " WPORT_WR p0 wmem [&1] @0 \n", + " WPORT_WR p0 wmem [&2] @0 \n", + " CALL virtual_z \n", + " WPORT_WR p0 wmem [&0] @123 \n", + " WPORT_WR p0 wmem [&1] @123 \n", + " WPORT_WR p0 wmem [&2] @123 \n", + " WPORT_WR p0 wmem [&0] @246 \n", + " WPORT_WR p0 wmem [&1] @246 \n", + " WPORT_WR p0 wmem [&2] @246 \n", + " CALL virtual_z \n", + " WPORT_WR p0 wmem [&0] @369 \n", + " WPORT_WR p0 wmem [&1] @369 \n", + " WPORT_WR p0 wmem [&2] @369 \n", + " REG_WR r_wave wmem [&0] \n", + " REG_WR w1 imm #0 \n", + " WMEM_WR &0 \n", + " REG_WR r_wave wmem [&1] \n", + " REG_WR w1 imm #0 \n", + " WMEM_WR &1 \n", + " REG_WR r_wave wmem [&2] \n", + " REG_WR w1 imm #0 \n", + " WMEM_WR &2 \n", + " WAIT @706 time \n", + " TIME #1013 inc_ref \n", + " REG_WR s12 op -op(s12 + #1) \n", + " TEST -op(r0 - #1) \n", + " JUMP reps -if(NZ) -wr(r0 op) -op(r0 + #1) \n", + " JUMP HERE \n", + "virtual_z:\n", + " REG_WR r_wave wmem [&0] \n", + " REG_WR r1 imm #1073741824 \n", + " REG_WR w1 op -op(w1 + r1) \n", + " WMEM_WR &0 \n", + " REG_WR r_wave wmem [&1] \n", + " REG_WR r1 imm #1073741824 \n", + " REG_WR w1 op -op(w1 + r1) \n", + " WMEM_WR &1 \n", + " REG_WR r_wave wmem [&2] \n", + " REG_WR r1 imm #1073741824 \n", + " REG_WR w1 op -op(w1 + r1) \n", + " WMEM_WR &2 \n", + "RET\n", + "\n", + "\n" + ] + } + ], + "source": [ + "class VirtualZProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " \n", + " self.declare_gen(ch=gen_ch, nqz=1)\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'])\n", + "\n", + " # Define a Gaussian envelope for pulse shaping\n", + " ramp_len = 0.1\n", + " self.add_gauss(ch=gen_ch, name=\"ramp\", \n", + " sigma=ramp_len/10, \n", + " length=ramp_len, \n", + " even_length=True)\n", + " \n", + " # Define a flat-top pulse (has 3 waveforms: rise, flat, fall)\n", + " self.add_pulse(ch=gen_ch, name=\"my_pulse\", \n", + " style=\"flat_top\", \n", + " envelope=\"ramp\", \n", + " freq=cfg['freq'], \n", + " length=0.05,\n", + " phase=0,\n", + " gain=1.0)\n", + "\n", + " # Create a subroutine for virtual-Z (90-degree phase rotation)\n", + " sub = AsmV2()\n", + " for wname in self.list_pulse_waveforms(\"my_pulse\"):\n", + " sub.read_wmem(name=wname)\n", + " sub.inc_reg(dst='w_phase', src=self.deg2reg(90, gen_ch=gen_ch))\n", + " sub.write_wmem(name=wname)\n", + " self.add_subroutine(\"virtual_z\", sub)\n", + "\n", + " # Configure readout\n", + " self.add_readoutconfig(ch=ro_ch, name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=gen_ch)\n", + " self.send_readoutconfig(ch=ro_ch, name=\"my_ro\", t=0)\n", + " \n", + " def _body(self, cfg):\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'], ddr4=True)\n", + "\n", + " # Pulse 1: phase = 0\n", + " self.pulse(ch=cfg['gen_ch'], name=\"my_pulse\", t=0, tag='pulse1')\n", + " \n", + " # Apply virtual-Z (adds 90° to subsequent pulses)\n", + " self.call(\"virtual_z\")\n", + " \n", + " # Pulse 2: phase = 90°\n", + " self.pulse(ch=cfg['gen_ch'], name=\"my_pulse\", t=0.2, tag='pulse2')\n", + " \n", + " # Pulse 3: phase = 90° (same as pulse 2)\n", + " self.pulse(ch=cfg['gen_ch'], name=\"my_pulse\", t=0.4, tag='pulse3')\n", + " \n", + " # Apply another virtual-Z (adds another 90° → total 180°)\n", + " self.call(\"virtual_z\")\n", + " \n", + " # Pulse 4: phase = 180°\n", + " self.pulse(ch=cfg['gen_ch'], name=\"my_pulse\", t=0.6, tag='pulse4')\n", + " \n", + " # Reset phase to 0 for next shot\n", + " for wname in self.list_pulse_waveforms(\"my_pulse\"):\n", + " self.read_wmem(name=wname)\n", + " self.write_reg(dst='w_phase', src=0)\n", + " self.write_wmem(name=wname)\n", + "\n", + "# Configuration\n", + "config_vz = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500,\n", + " 'trig_time': 0.25,\n", + " 'ro_len': 0.9\n", + "}\n", + "\n", + "# Run the program\n", + "prog = VirtualZProgram(soccfg, reps=2, final_delay=0.5, cfg=config_vz)\n", + "iq_data = prog.acquire_decimated(soc, rounds=10)\n", + "time_axis = prog.get_time_axis(ro_index=0)\n", + "\n", + "# Plot results for each repetition\n", + "fig, axes = plt.subplots(len(iq_data[0]), 1, figsize=(10, 6))\n", + "if len(iq_data[0]) == 1:\n", + " axes = [axes]\n", + "\n", + "for rep, iq in enumerate(iq_data[0]):\n", + " ax = axes[rep]\n", + " ax.plot(time_axis, iq[:,0], label='I')\n", + " ax.plot(time_axis, iq[:,1], label='Q')\n", + " ax.plot(time_axis, np.abs(iq.dot([1,1j])), label='Magnitude')\n", + " ax.legend()\n", + " ax.set_title(f\"Repetition {rep}\")\n", + " ax.set_ylabel(\"Amplitude (a.u.)\")\n", + " ax.set_xlabel(\"Time (µs)\")\n", + " ax.grid(True)\n", + "\n", + "plt.tight_layout()\n", + "plt.show()\n", + "\n", + "# Inspect the subroutine in the compiled program\n", + "print(\"\\n=== Virtual-Z Subroutine ASM ===\")\n", + "print(prog.asm())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Explanation:**\n", + "- The virtual-Z subroutine reads each waveform, adds 90° to its phase, and writes it back\n", + "- `deg2reg()` converts degrees to the tProc's internal phase units\n", + "- After the sequence, we reset the phase to 0 for the next shot\n", + "- Subroutines are defined using `AsmV2()` and added with `add_subroutine()`\n", + "- Called with `call(\"name\")`\n", + "- Use `asm_subroutine()` to see the generated assembly for a subroutine" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Understanding Waveform Structure\n", + "\n", + "Different pulse styles have different waveform counts:\n", + "- `const` - 1 waveform\n", + "- `arb` (arbitrary/envelope) - 1 waveform\n", + "- `flat_top` - 3 waveforms (rise, flat, fall)\n", + "\n", + "You can list waveforms for any pulse:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Waveforms for 'my_pulse':\n", + " my_pulse_w0\n", + " my_pulse_w1\n", + " my_pulse_w2\n", + "\n", + "First waveform parameters: {'freq': QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), 'phase': QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), 'env': 0, 'gain': QickRawParam(par='gain', start=32766, spans={}, quantize=2, steps={}), 'length': 31, 'conf': 8, 'name': 'my_pulse_w0'}\n" + ] + } + ], + "source": [ + "print(\"Waveforms for 'my_pulse':\")\n", + "for wname in prog.list_pulse_waveforms(\"my_pulse\"):\n", + " print(f\" {wname}\")\n", + "\n", + "# You can also inspect parameters of individual waveforms\n", + "waveform = prog.pulses['my_pulse'].waveforms[0]\n", + "print(f\"\\nFirst waveform parameters: {waveform.__dict__}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Subroutines for Code Reuse\n", + "\n", + "Subroutines are useful for code that repeats across multiple places in your program. They can be called multiple times." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== Subroutine macro_list ===\n", + "Pulse(ch=0, name='test_pulse', t=0, tag=None, t_params={'t': }, t_regs={'t': 0})\n", + "Delay(t=0.15, auto=False, tag=None, t_params={'t': }, t_regs={'t': 92})\n", + "Pulse(ch=0, name='test_pulse', t=0, tag=None, t_params={'t': }, t_regs={'t': 0})\n", + "\n", + "=== Fully compiled program ===\n", + " NOP \n", + " REG_WR s12 imm #0 \n", + " WPORT_WR p3 wmem [&1] @0 \n", + " TIME #614 inc_ref \n", + " REG_WR r0 imm #0 \n", + "reps:\n", + " DPORT_WR p0 imm 1 @154 \n", + " TRIG p0 set @154 \n", + " DPORT_WR p0 imm 0 @164 \n", + " TRIG p0 clr @164 \n", + " CALL pulse_pair \n", + " TIME #123 inc_ref \n", + " CALL pulse_pair \n", + " WAIT @953 time \n", + " TIME #1260 inc_ref \n", + " REG_WR s12 op -op(s12 + #1) \n", + " TEST -op(r0 - #0) \n", + " JUMP reps -if(NZ) -wr(r0 op) -op(r0 + #1) \n", + " JUMP HERE \n", + "pulse_pair:\n", + " WPORT_WR p0 wmem [&0] @0 \n", + " TIME #92 inc_ref \n", + " WPORT_WR p0 wmem [&0] @0 \n", + "RET\n", + "\n", + "\n" + ] + } + ], + "source": [ + "class SubroutineExampleProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + "\n", + " # Define a simple pulse\n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"test_pulse\", \n", + " style=\"const\", \n", + " freq=cfg['freq'], length=0.1,\n", + " phase=0, gain=1.0)\n", + "\n", + " # Define a subroutine that plays a pulse sequence\n", + " sub = AsmV2()\n", + " sub.pulse(ch=cfg['gen_ch'], name=\"test_pulse\", t=0)\n", + " sub.delay(0.15)\n", + " sub.pulse(ch=cfg['gen_ch'], name=\"test_pulse\", t=0)\n", + " self.add_subroutine(\"pulse_pair\", sub)\n", + "\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=cfg['gen_ch'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", t=0)\n", + " \n", + " def _body(self, cfg):\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'])\n", + " \n", + " # Call the subroutine multiple times\n", + " self.call(\"pulse_pair\") # First pair\n", + " self.delay(0.2)\n", + " self.call(\"pulse_pair\") # Second pair\n", + "\n", + "config_sub = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500,\n", + " 'trig_time': 0.25,\n", + " 'ro_len': 1.5\n", + "}\n", + "\n", + "prog = SubroutineExampleProgram(soccfg, reps=1, final_delay=0.5, cfg=config_sub)\n", + "\n", + "print(\"=== Subroutine macro_list ===\")\n", + "for inst in prog.subroutines['pulse_pair'].macro_list:\n", + " print(inst)\n", + "\n", + "print(\"\\n=== Fully compiled program ===\")\n", + "print(prog.asm())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Benefits of subroutines:**\n", + "- Reduce program size (important since program memory is limited to 4096 words)\n", + "- Make code more readable and maintainable\n", + "- Allow complex sequences to be built from reusable components\n", + "\n", + "**Limitation:** The timeline management code doesn't understand jumps. If your subroutine contains timed instructions, ensure the timeline is consistent before and after the call. For simple pulse sequences without timeline dependencies, subroutines work well." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. Dynamic Gain Modulation\n", + "\n", + "You can also update gain dynamically to implement amplitude modulation." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "728f48b71daf4c6db5d8457e60467735", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/10 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "class GainModulationProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + " \n", + " # Define a Gaussian envelope\n", + " ramp_len = 0.1\n", + " self.add_gauss(ch=cfg['gen_ch'], name=\"ramp\", \n", + " sigma=ramp_len/10, length=ramp_len, even_length=True)\n", + " \n", + " # Define three pulses with different gains\n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"pulse_full\", \n", + " style=\"flat_top\", envelope=\"ramp\",\n", + " freq=cfg['freq'], length=0.05, phase=0, gain=1.0)\n", + " \n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"pulse_half\", \n", + " style=\"flat_top\", envelope=\"ramp\",\n", + " freq=cfg['freq'], length=0.05, phase=0, gain=0.5)\n", + " \n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"pulse_quarter\", \n", + " style=\"flat_top\", envelope=\"ramp\",\n", + " freq=cfg['freq'], length=0.05, phase=0, gain=0.25)\n", + " \n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=cfg['gen_ch'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", t=0)\n", + " \n", + " def _body(self, cfg):\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'], ddr4=True)\n", + " \n", + " # Pulse with full gain\n", + " self.pulse(ch=cfg['gen_ch'], name=\"pulse_full\", t=0, tag='pulse_full')\n", + " \n", + " # Pulse with half gain\n", + " self.pulse(ch=cfg['gen_ch'], name=\"pulse_half\", t=0.2, tag='pulse_half')\n", + " \n", + " # Pulse with quarter gain\n", + " self.pulse(ch=cfg['gen_ch'], name=\"pulse_quarter\", t=0.4, tag='pulse_quarter')\n", + "\n", + "\n", + "prog = GainModulationProgram(soccfg, reps=1, final_delay=0.5, cfg=config_sub)\n", + "iq_data = prog.acquire_decimated(soc, rounds=10)\n", + "time_axis = prog.get_time_axis(ro_index=0)\n", + "\n", + "plt.figure(figsize=(10, 6))\n", + "plt.plot(time_axis, iq_data[0][:,0], label='I')\n", + "plt.plot(time_axis, iq_data[0][:,1], label='Q')\n", + "plt.plot(time_axis, np.abs(iq_data[0].dot([1,1j])), label='Magnitude')\n", + "plt.legend()\n", + "plt.xlabel('Time (µs)')\n", + "plt.ylabel('Amplitude (a.u.)')\n", + "plt.title('Dynamic Gain Modulation')\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note on gain operations:**\n", + "- Gain is stored as a 16-bit integer (0-32766 for full scale)\n", + "- Shifting right (>>) divides by 2\n", + "- Shifting left (<<) multiplies by 2\n", + "- Be careful not to exceed the maximum value (32766)\n", + "- Use `reg_op()` for arithmetic operations on registers" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 7. Inspecting Waveform Memory\n", + "\n", + "You can inspect the contents of waveform memory for debugging." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "All defined pulses:\n", + "\n", + "Pulse: pulse_full\n", + " type: \n", + " waveforms: [Waveform(name='pulse_full_w0', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=32766, spans={}, quantize=2, steps={}), length=31, conf=8), Waveform(name='pulse_full_w1', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=16383, spans={}, quantize=1, steps={}), length=QickRawParam(par='length', start=31, spans={}, quantize=1, steps={}), conf=9), Waveform(name='pulse_full_w2', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=31, gain=QickRawParam(par='gain', start=32766, spans={}, quantize=2, steps={}), length=31, conf=8)]\n", + " waveform: Waveform(name='pulse_full_w0', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=32766, spans={}, quantize=2, steps={}), length=31, conf=8)\n", + " attributes: ['compile', 'conf', 'env', 'fill_steps', 'freq', 'gain', 'get', 'items', 'keys', 'length', 'name', 'phase', 'sweeps', 'to_dict', 'values', 'widths']\n", + " waveform: Waveform(name='pulse_full_w1', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=16383, spans={}, quantize=1, steps={}), length=QickRawParam(par='length', start=31, spans={}, quantize=1, steps={}), conf=9)\n", + " attributes: ['compile', 'conf', 'env', 'fill_steps', 'freq', 'gain', 'get', 'items', 'keys', 'length', 'name', 'phase', 'sweeps', 'to_dict', 'values', 'widths']\n", + " waveform: Waveform(name='pulse_full_w2', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=31, gain=QickRawParam(par='gain', start=32766, spans={}, quantize=2, steps={}), length=31, conf=8)\n", + " attributes: ['compile', 'conf', 'env', 'fill_steps', 'freq', 'gain', 'get', 'items', 'keys', 'length', 'name', 'phase', 'sweeps', 'to_dict', 'values', 'widths']\n", + "\n", + "Pulse: pulse_half\n", + " type: \n", + " waveforms: [Waveform(name='pulse_half_w0', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=16382, spans={}, quantize=2, steps={}), length=31, conf=8), Waveform(name='pulse_half_w1', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=8191, spans={}, quantize=1, steps={}), length=QickRawParam(par='length', start=31, spans={}, quantize=1, steps={}), conf=9), Waveform(name='pulse_half_w2', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=31, gain=QickRawParam(par='gain', start=16382, spans={}, quantize=2, steps={}), length=31, conf=8)]\n", + " waveform: Waveform(name='pulse_half_w0', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=16382, spans={}, quantize=2, steps={}), length=31, conf=8)\n", + " attributes: ['compile', 'conf', 'env', 'fill_steps', 'freq', 'gain', 'get', 'items', 'keys', 'length', 'name', 'phase', 'sweeps', 'to_dict', 'values', 'widths']\n", + " waveform: Waveform(name='pulse_half_w1', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=8191, spans={}, quantize=1, steps={}), length=QickRawParam(par='length', start=31, spans={}, quantize=1, steps={}), conf=9)\n", + " attributes: ['compile', 'conf', 'env', 'fill_steps', 'freq', 'gain', 'get', 'items', 'keys', 'length', 'name', 'phase', 'sweeps', 'to_dict', 'values', 'widths']\n", + " waveform: Waveform(name='pulse_half_w2', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=31, gain=QickRawParam(par='gain', start=16382, spans={}, quantize=2, steps={}), length=31, conf=8)\n", + " attributes: ['compile', 'conf', 'env', 'fill_steps', 'freq', 'gain', 'get', 'items', 'keys', 'length', 'name', 'phase', 'sweeps', 'to_dict', 'values', 'widths']\n", + "\n", + "Pulse: pulse_quarter\n", + " type: \n", + " waveforms: [Waveform(name='pulse_quarter_w0', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=8190, spans={}, quantize=2, steps={}), length=31, conf=8), Waveform(name='pulse_quarter_w1', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=4095, spans={}, quantize=1, steps={}), length=QickRawParam(par='length', start=31, spans={}, quantize=1, steps={}), conf=9), Waveform(name='pulse_quarter_w2', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=31, gain=QickRawParam(par='gain', start=8190, spans={}, quantize=2, steps={}), length=31, conf=8)]\n", + " waveform: Waveform(name='pulse_quarter_w0', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=8190, spans={}, quantize=2, steps={}), length=31, conf=8)\n", + " attributes: ['compile', 'conf', 'env', 'fill_steps', 'freq', 'gain', 'get', 'items', 'keys', 'length', 'name', 'phase', 'sweeps', 'to_dict', 'values', 'widths']\n", + " waveform: Waveform(name='pulse_quarter_w1', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=4095, spans={}, quantize=1, steps={}), length=QickRawParam(par='length', start=31, spans={}, quantize=1, steps={}), conf=9)\n", + " attributes: ['compile', 'conf', 'env', 'fill_steps', 'freq', 'gain', 'get', 'items', 'keys', 'length', 'name', 'phase', 'sweeps', 'to_dict', 'values', 'widths']\n", + " waveform: Waveform(name='pulse_quarter_w2', freq=QickRawParam(par='freq', start=218453333, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=31, gain=QickRawParam(par='gain', start=8190, spans={}, quantize=2, steps={}), length=31, conf=8)\n", + " attributes: ['compile', 'conf', 'env', 'fill_steps', 'freq', 'gain', 'get', 'items', 'keys', 'length', 'name', 'phase', 'sweeps', 'to_dict', 'values', 'widths']\n", + "\n", + "Pulse: my_ro\n", + " type: \n", + " waveforms: [Waveform(name='my_ro_w0', freq=QickRawParam(par='freq', start=-873813332, spans={}, quantize=-4, steps={}), phase=0, env=0, gain=0, length=3, conf=520)]\n", + " waveform: Waveform(name='my_ro_w0', freq=QickRawParam(par='freq', start=-873813332, spans={}, quantize=-4, steps={}), phase=0, env=0, gain=0, length=3, conf=520)\n", + " attributes: ['compile', 'conf', 'env', 'fill_steps', 'freq', 'gain', 'get', 'items', 'keys', 'length', 'name', 'phase', 'sweeps', 'to_dict', 'values', 'widths']\n" + ] + } + ], + "source": [ + "# Print all defined pulses after program execution\n", + "print(\"All defined pulses:\")\n", + "for pulse_name, pulse_obj in prog.pulses.items():\n", + " print(f\"\\nPulse: {pulse_name}\")\n", + " print(f\" type: {type(pulse_obj)}\")\n", + " print(f\" waveforms: {pulse_obj.waveforms}\")\n", + " for waveform in pulse_obj.waveforms:\n", + " print(f\" waveform: {waveform}\")\n", + " print(f\" attributes: {[a for a in dir(waveform) if not a.startswith('_')]}\")\n", + "\n", + "# You can also read waveform memory from the board\n", + "# This requires knowing the waveform addresses\n", + "# waddr = prog.pulse_waveform_addrs['my_pulse']['my_pulse_w0']\n", + "# waveform_data = soc.read_mem(length=100, mem_sel='wmem', addr=waddr)\n", + "# Note: read_mem returns data as 32-bit integers; you may need to reinterpret as 16-bit I/Q pairs" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 8. Summary\n", + "\n", + "You have learned:\n", + "- How to read, modify, and write waveforms dynamically using waveform registers\n", + "- How to implement virtual-Z gates by updating pulse phase\n", + "- How to create and use subroutines for code reuse\n", + "- How to modulate gain dynamically\n", + "- How to inspect waveform parameters\n", + "- How to use `read_mem()` to read waveform memory for debugging\n", + "\n", + "**Key concepts:**\n", + "- Waveform memory stores pulse definitions that can be modified at runtime\n", + "- Subroutines save program memory and improve code organization\n", + "- The tProc can update waveform parameters in microseconds, enabling adaptive pulse shaping\n", + "- Always reset modified parameters between shots unless persistence is intended\n", + "\n", + "**Next steps:** Proceed to [`06_Generators_And_Readouts.ipynb`](./06_Generators_And_Readouts.ipynb) to learn about the different generators and readout in QICK." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/source/tutorials/06_Generators_And_Readouts.ipynb b/docs/source/tutorials/06_Generators_And_Readouts.ipynb new file mode 100644 index 000000000..67002c146 --- /dev/null +++ b/docs/source/tutorials/06_Generators_And_Readouts.ipynb @@ -0,0 +1,1594 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 06 - Generators and Readouts\n", + "\n", + "**Objective:** Learn how to use waveform generators and optimize readout resonators. This notebook covers:\n", + "- Generator configuration and waveform styles\n", + "- Readout resonator tuning and optimization\n", + "- IQ mixing and signal processing\n", + "- Frequency sweeps for resonator characterization" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%pybind11/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Standard imports\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import logging\n", + "\n", + "from qick import *\n", + "from qick.asm_v2 import AveragerProgramV2\n", + "\n", + "# Setup logging\n", + "logging.basicConfig(level=logging.INFO, format='%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s')\n", + "logging.getLogger(\"qick_processor\").setLevel(logging.WARNING)\n", + "\n", + "# Connect to the board (adjust the path to your firmware)\n", + "BITSTREAM_PATH = 'qick_216.bit'#'/path/to/your/firmware.bit' # <--- CHANGE THIS\n", + "soc = QickSoc(BITSTREAM_PATH)\n", + "soccfg = soc\n", + "\n", + "# Define hardware channels\n", + "GEN_CH = 0 # Generator channel (DAC)\n", + "RO_CH = 0 # Readout channel (ADC)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Understanding Waveform Generators\n", + "\n", + "The QICK board has multiple DAC channels that can generate arbitrary waveforms. Each generator can produce:\n", + "- **Constant pulses** (`style=\"const\"`): Square pulses with constant amplitude\n", + "- **Arbitrary/envelope pulses** (`style=\"arb\"`): Shaped pulses using a predefined envelope\n", + "- **Flat-top pulses** (`style=\"flat_top\"`): Gaussian rise/fall with constant middle section\n", + "\n", + "Let's explore each type." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Generator Configuration: Constant Pulse\n", + "\n", + "The simplest waveform is a constant pulse. It has a flat amplitude over its duration." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "ef20eb1bd91e4243b64850aa80326d4a", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/10 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "class ConstantPulseProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + "\n", + " # Constant pulse - square shape\n", + " self.add_pulse(\n", + " ch=cfg['gen_ch'],\n", + " name=\"const_pulse\",\n", + " style=\"const\",\n", + " freq=cfg['freq'],\n", + " length=cfg['pulse_len'],\n", + " phase=cfg['phase'],\n", + " gain=cfg['gain']\n", + " )\n", + "\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=cfg['gen_ch'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", t=0)\n", + "\n", + " def _body(self, cfg):\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'])\n", + " self.pulse(ch=cfg['gen_ch'], name=\"const_pulse\", t=0)\n", + "\n", + "# Configure and run\n", + "config_const = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 100.0,\n", + " 'pulse_len': 0.2,\n", + " 'phase': 0,\n", + " 'gain': 0.8,\n", + " 'trig_time': 0.25,\n", + " 'ro_len': 0.5\n", + "}\n", + "\n", + "prog = ConstantPulseProgram(soccfg, reps=1, final_delay=1.0, cfg=config_const)\n", + "iq_data = prog.acquire_decimated(soc, rounds=10)\n", + "time_axis = prog.get_time_axis(ro_index=0)\n", + "\n", + "plt.figure(figsize=(10, 4))\n", + "plt.plot(time_axis, iq_data[0][:,0], label='I')\n", + "plt.plot(time_axis, iq_data[0][:,1], label='Q')\n", + "plt.legend()\n", + "plt.xlabel('Time (µs)')\n", + "plt.ylabel('Amplitude (a.u.)')\n", + "plt.title('Constant Pulse - I/Q Components')\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Observation:** The constant pulse produces a square-shaped response. The I and Q components oscillate at the carrier frequency (100 MHz in this case)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Shaped Pulses with Envelopes\n", + "\n", + "Shaped pulses reduce spectral leakage and are essential for qubit control. The QICK supports:\n", + "- **Gaussian envelopes**: Smooth rise and fall\n", + "- **Flat-top pulses**: Gaussian edges with a constant top (ideal for readout resonators)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "0107848e31464010aaf97db383b65fab", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/10 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "class ShapedPulseProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + "\n", + " # Define a Gaussian envelope\n", + " # The envelope length should be sufficient to capture the full pulse\n", + " ramp_len = 0.15\n", + " self.add_gauss(\n", + " ch=cfg['gen_ch'],\n", + " name=\"gauss_env\",\n", + " sigma=ramp_len / 8, # Steepness of the Gaussian\n", + " length=ramp_len,\n", + " even_length=True\n", + " )\n", + "\n", + " # Gaussian pulse (arbitrary envelope)\n", + " self.add_pulse(\n", + " ch=cfg['gen_ch'], name=\"gauss_pulse\",\n", + " style=\"arb\", envelope=\"gauss_env\",\n", + " freq=cfg['freq'], phase=cfg['phase'], gain=cfg['gain']\n", + " )\n", + "\n", + " # Flat-top pulse (good for readout)\n", + " self.add_pulse(\n", + " ch=cfg['gen_ch'], name=\"flattop_pulse\",\n", + " style=\"flat_top\", envelope=\"gauss_env\",\n", + " freq=cfg['freq'], length=0.2, phase=cfg['phase'], gain=cfg['gain']\n", + " )\n", + "\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=cfg['gen_ch'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", t=0)\n", + "\n", + " def _body(self, cfg):\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'], ddr4=True)\n", + " self.pulse(ch=cfg['gen_ch'], name=\"gauss_pulse\", t=0, tag='gauss')\n", + " self.pulse(ch=cfg['gen_ch'], name=\"flattop_pulse\", t=0.5, tag='flattop')\n", + "\n", + "config_shaped = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 100.0,\n", + " 'phase': 0,\n", + " 'gain': 0.8,\n", + " 'trig_time': 0.1,\n", + " 'ro_len': 1.0\n", + "}\n", + "\n", + "prog = ShapedPulseProgram(soccfg, reps=1, final_delay=0.5, cfg=config_shaped)\n", + "iq_data = prog.acquire_decimated(soc, rounds=10)\n", + "time_axis = prog.get_time_axis(ro_index=0)\n", + "\n", + "# Separate the two pulses\n", + "magnitude = np.abs(iq_data[0].dot([1, 1j]))\n", + "\n", + "plt.figure(figsize=(12, 5))\n", + "plt.subplot(1, 2, 1)\n", + "plt.plot(time_axis, magnitude, label='Magnitude')\n", + "plt.axvline(x=0.25, color='r', linestyle='--', alpha=0.5, label='Gaussian peak')\n", + "plt.axvline(x=0.75, color='g', linestyle='--', alpha=0.5, label='Flat-top peak')\n", + "plt.xlabel('Time (µs)')\n", + "plt.ylabel('Magnitude (a.u.)')\n", + "plt.title('Shaped Pulses: Magnitude')\n", + "plt.legend()\n", + "plt.grid(True)\n", + "\n", + "plt.subplot(1, 2, 2)\n", + "plt.plot(time_axis, iq_data[0][:,0], label='I')\n", + "plt.plot(time_axis, iq_data[0][:,1], label='Q')\n", + "plt.xlabel('Time (µs)')\n", + "plt.ylabel('Amplitude (a.u.)')\n", + "plt.title('Shaped Pulses: I/Q Components')\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Key points about shaped pulses:**\n", + "- Gaussian pulses minimize spectral sidebands, reducing crosstalk\n", + "- Flat-top pulses maintain constant amplitude at the top, ideal for readout resonators\n", + "- The envelope is applied to the pulse shape, not the carrier frequency" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. IQ Mixing and Quadrature Signals\n", + "\n", + "The QICK uses IQ mixing to generate arbitrary phase shifts. I (in-phase) and Q (quadrature) components are 90° apart. By adjusting the phase parameter, you can rotate the pulse in the IQ plane." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "02b21b1a767d4b5b90b415cda53fe95b", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/10 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "class IQMixingProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + "\n", + " # Same pulse at different phases\n", + " for phase in cfg['phases']:\n", + " self.add_pulse(\n", + " ch=cfg['gen_ch'],\n", + " name=f\"pulse_{phase}\",\n", + " style=\"const\",\n", + " freq=cfg['freq'],\n", + " length=cfg['pulse_len'],\n", + " phase=phase,\n", + " gain=cfg['gain']\n", + " )\n", + "\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=cfg['gen_ch'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", t=0)\n", + "\n", + " def _body(self, cfg):\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'], ddr4=True)\n", + " for i, phase in enumerate(cfg['phases']):\n", + " self.pulse(ch=cfg['gen_ch'], name=f\"pulse_{phase}\", t=i * 0.3)\n", + "\n", + "config_iq = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500.0,\n", + " 'pulse_len': 0.1,\n", + " 'gain': 0.8,\n", + " 'trig_time': 0.05,\n", + " 'ro_len': 1.5,\n", + " 'phases': [0, 45, 90, 135, 180, 225, 270, 315]\n", + "}\n", + "\n", + "prog = IQMixingProgram(soccfg, reps=1, final_delay=0.5, cfg=config_iq)\n", + "iq_data = prog.acquire_decimated(soc, rounds=10)\n", + "time_axis = prog.get_time_axis(ro_index=0)\n", + "\n", + "# Extract magnitude at each pulse center\n", + "pulse_centers = [0.15 + i * 0.3 for i in range(len(config_iq['phases']))]\n", + "idx_centers = [np.argmin(np.abs(time_axis - t)) for t in pulse_centers]\n", + "iq_at_centers = iq_data[0][idx_centers, :]\n", + "\n", + "plt.figure(figsize=(12, 5))\n", + "plt.subplot(1, 2, 1)\n", + "plt.plot(time_axis, iq_data[0][:,0], label='I')\n", + "plt.plot(time_axis, iq_data[0][:,1], label='Q')\n", + "plt.xlabel('Time (µs)')\n", + "plt.ylabel('Amplitude (a.u.)')\n", + "plt.title('IQ Mixing - Multiple Phases')\n", + "plt.legend()\n", + "plt.grid(True)\n", + "\n", + "plt.subplot(1, 2, 2)\n", + "plt.plot(iq_at_centers[:,0], iq_at_centers[:,1], 'o-', markersize=8)\n", + "for i, phase in enumerate(config_iq['phases']):\n", + " plt.annotate(f'{phase}°', (iq_at_centers[i,0], iq_at_centers[i,1]))\n", + "plt.axhline(0, color='k', linestyle='-', alpha=0.3)\n", + "plt.axvline(0, color='k', linestyle='-', alpha=0.3)\n", + "plt.xlabel('I')\n", + "plt.ylabel('Q')\n", + "plt.title('IQ Constellation')\n", + "plt.axis('equal')\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Explanation of IQ mixing:**\n", + "- Phase shifts rotate the pulse vector in the IQ plane\n", + "- A pulse with phase 0° appears on the I axis\n", + "- A pulse with phase 90° appears on the Q axis\n", + "- The constellation plot shows the relationship between I and Q for different phases" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. Readout Resonator Characterization\n", + "\n", + "Readout resonators are used to measure qubit states. To optimize the readout, we need to find the resonator's resonant frequency. This is done by sweeping the readout frequency and measuring the response." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Sweeping readout frequency...\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "f3d926ff7ce243bc92a757f482df9b04", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/100 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Resonance frequency: 509.50 MHz\n", + "Maximum magnitude: 391.372 a.u.\n" + ] + } + ], + "source": [ + "class ReadoutSweepProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + "\n", + " # Define the readout pulse (flat-top recommended for readout)\n", + " ramp_len = 0.05\n", + " self.add_gauss(ch=cfg['gen_ch'], name=\"ramp\", \n", + " sigma=ramp_len/8, length=ramp_len, even_length=True)\n", + " \n", + " self.add_pulse(\n", + " ch=cfg['gen_ch'], name=\"readout_pulse\",\n", + " style=\"flat_top\", envelope=\"ramp\",\n", + " freq=cfg['freq'], length=cfg['pulse_len'], phase=0, gain=cfg['gain']\n", + " )\n", + "\n", + " # Configure readout - freq will be swept\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=cfg['gen_ch'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", t=0)\n", + "\n", + " def _body(self, cfg):\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'], ddr4=True)\n", + " self.pulse(ch=cfg['gen_ch'], name=\"readout_pulse\", t=0)\n", + "\n", + "# Frequency sweep parameters\n", + "freqs = np.linspace(490, 510, 41) # MHz\n", + "results_i = []\n", + "results_q = []\n", + "\n", + "base_config = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'pulse_len': 0.5,\n", + " 'gain': 0.5,\n", + " 'trig_time': 0.1,\n", + " 'ro_len': 0.8\n", + "}\n", + "\n", + "print(\"Sweeping readout frequency...\")\n", + "for f in freqs:\n", + " config = base_config.copy()\n", + " config['freq'] = f\n", + " prog = ReadoutSweepProgram(soccfg, reps=1, final_delay=0.5, cfg=config)\n", + " iq_data = prog.acquire_decimated(soc, rounds=100) # 100 averages for clean data\n", + " \n", + " # Average the I/Q data over the pulse duration\n", + " # (take mean after the pulse has settled)\n", + " start_idx = int(0.2 / prog.get_time_axis(ro_index=0)[1]) # 0.2 us after trigger\n", + " i_avg = np.mean(iq_data[0][start_idx:, 0])\n", + " q_avg = np.mean(iq_data[0][start_idx:, 1])\n", + " results_i.append(i_avg)\n", + " results_q.append(q_avg)\n", + "\n", + "results_mag = np.sqrt(np.array(results_i)**2 + np.array(results_q)**2)\n", + "results_phase = np.arctan2(results_q, results_i) * 180 / np.pi\n", + "\n", + "plt.figure(figsize=(12, 5))\n", + "plt.subplot(1, 2, 1)\n", + "plt.plot(freqs, results_mag, 'o-', linewidth=2, markersize=4)\n", + "plt.xlabel('Frequency (MHz)')\n", + "plt.ylabel('|IQ| (a.u.)')\n", + "plt.title('Readout Resonator - Magnitude Response')\n", + "plt.grid(True)\n", + "\n", + "plt.subplot(1, 2, 2)\n", + "plt.plot(freqs, results_phase, 'o-', linewidth=2, markersize=4)\n", + "plt.xlabel('Frequency (MHz)')\n", + "plt.ylabel('Phase (degrees)')\n", + "plt.title('Readout Resonator - Phase Response')\n", + "plt.grid(True)\n", + "plt.tight_layout()\n", + "plt.show()\n", + "\n", + "# Find the resonance frequency (minimum magnitude for a dispersive readout)\n", + "resonance_idx = np.argmin(results_mag)\n", + "resonance_freq = freqs[resonance_idx]\n", + "print(f\"\\nResonance frequency: {resonance_freq:.2f} MHz\")\n", + "print(f\"Maximum magnitude: {results_mag[resonance_idx]:.3f} a.u.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Interpreting the readout sweep:**\n", + "- The magnitude response shows a dip at the resonance frequency\n", + "- The phase response shows a sharp transition (dispersion) at resonance\n", + "- For optimal readout, you typically operate slightly detuned from resonance\n", + "- The exact optimal point depends on your measurement protocol (e.g., homodyne vs. heterodyne)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 7. Optimizing Readout Parameters\n", + "\n", + "Once you find the resonance frequency, you can optimize other parameters like readout length and gain." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Optimizing readout length...\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b26f9106cd774f9badc3296a9502900b", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/100 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Optimal readout length: 1.10 µs\n", + "Maximum SNR: 7815.2\n" + ] + } + ], + "source": [ + "class ReadoutOptimizationProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + "\n", + " ramp_len = 0.05\n", + " self.add_gauss(ch=cfg['gen_ch'], name=\"ramp\", \n", + " sigma=ramp_len/8, length=ramp_len, even_length=True)\n", + " \n", + " self.add_pulse(\n", + " ch=cfg['gen_ch'], name=\"readout_pulse\",\n", + " style=\"flat_top\", envelope=\"ramp\",\n", + " freq=cfg['freq'], length=cfg['pulse_len'], phase=0, gain=cfg['gain']\n", + " )\n", + "\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=cfg['gen_ch'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", t=0)\n", + "\n", + " def _body(self, cfg):\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'], ddr4=True)\n", + " self.pulse(ch=cfg['gen_ch'], name=\"readout_pulse\", t=0)\n", + "\n", + "# Use the found resonance frequency\n", + "optimal_freq = resonance_freq if 'resonance_freq' in dir() else 500.0\n", + "\n", + "# Sweep readout length\n", + "lengths = np.linspace(0.2, 2.0, 19)\n", + "snr_results = []\n", + "\n", + "print(\"Optimizing readout length...\")\n", + "for l in lengths:\n", + " config = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': optimal_freq,\n", + " 'pulse_len': l,\n", + " 'gain': 0.5,\n", + " 'trig_time': 0.1,\n", + " 'ro_len': l + 0.1 # Readout slightly longer than pulse\n", + " }\n", + " prog = ReadoutOptimizationProgram(soccfg, reps=1, final_delay=0.5, cfg=config)\n", + " iq_data = prog.acquire_decimated(soc, rounds=100)\n", + " \n", + " # Estimate SNR from signal magnitude\n", + " signal_mag = np.abs(iq_data[0].dot([1, 1j]))\n", + " signal_peak = np.max(signal_mag)\n", + " noise_std = np.std(signal_mag[:50]) # Noise before the pulse\n", + " snr = signal_peak / noise_std if noise_std > 0 else 0\n", + " snr_results.append(snr)\n", + "\n", + "plt.figure(figsize=(10, 5))\n", + "plt.plot(lengths, snr_results, 'o-', linewidth=2, markersize=6)\n", + "plt.xlabel('Readout Pulse Length (µs)')\n", + "plt.ylabel('Signal-to-Noise Ratio (SNR)')\n", + "plt.title('Readout Optimization - SNR vs. Pulse Length')\n", + "plt.grid(True)\n", + "plt.show()\n", + "\n", + "optimal_idx = np.argmax(snr_results)\n", + "optimal_length = lengths[optimal_idx]\n", + "print(f\"\\nOptimal readout length: {optimal_length:.2f} µs\")\n", + "print(f\"Maximum SNR: {snr_results[optimal_idx]:.1f}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 8. Summary\n", + "\n", + "You have learned:\n", + "- How to configure generators with different pulse styles (constant, Gaussian, flat-top)\n", + "- How IQ mixing works and how phase shifts affect the IQ plane\n", + "- How to characterize a readout resonator via frequency sweeps\n", + "- How to optimize readout parameters like pulse length\n", + "\n", + "**Key takeaways:**\n", + "- Use shaped pulses (Gaussian or flat-top) for better spectral purity\n", + "- IQ mixing allows arbitrary phase control of your pulses\n", + "- Readout resonators should be characterized before experiments\n", + "- The optimal readout frequency is often slightly detuned from resonance\n", + "\n", + "**Next steps:** Proceed to [`07_Advanced_Generators_And_Readouts`](./07_Advanced_Generators_And_Readouts.ipynb) to learn about the DDR4 and MR buffers for high-speed data capture." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/source/tutorials/07_Advanced_Generators_And_Readouts.ipynb b/docs/source/tutorials/07_Advanced_Generators_And_Readouts.ipynb new file mode 100644 index 000000000..4a6df9e4d --- /dev/null +++ b/docs/source/tutorials/07_Advanced_Generators_And_Readouts.ipynb @@ -0,0 +1,2174 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 07 - Advanced Generators and Readouts in tProc v2\n", + "\n", + "**Objective:** Explore the advanced generator and readout blocks available in the QICK firmware. This notebook covers:\n", + "\n", + "1. Muxed Generators (full-speed and mixer-mux) with Muxed Readouts (PFB)\n", + "2. Interpolated Generators vs. Standard Readouts (frequency matching in tProc v2 vs. v1)\n", + "3. Dynamically Configured Readouts for frequency sweeps and electrical delay calibration\n", + "4. Fast Dynamic Readout for phase-reset applications\n", + "5. IQ offset measurement and correction\n", + "6. Performance benchmarks\n", + "7. Real-time phase tracking\n", + "8. Common pitfalls and troubleshooting\n", + "9. Best practices summary\n", + "\n", + "**Prerequisites:** Complete the introductory tutorials ([`00_Getting_Started.ipynb`](./00_Getting_Started.ipynb) through [`06_Generators_And_Readouts.ipynb`](./06_Generators_And_Readouts.ipynb))." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connected to QICK board\n", + "Available generators (DACs): [0, 1, 2, 3, 4]\n", + "Available readouts (ADCs): [0, 1, 2, 3, 4, 5, 6]\n", + "tProc core version: 2.0\n", + "Sofware version: 0.2.381\n" + ] + } + ], + "source": [ + "# Standard imports\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import logging\n", + "import time\n", + "\n", + "from qick import *\n", + "from qick.asm_v2 import AveragerProgramV2, QickSweep1D, AsmV2\n", + "\n", + "# Setup logging\n", + "logging.basicConfig(level=logging.INFO, format='%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s')\n", + "\n", + "# Connect to the board (adjust path as needed)\n", + "BITSTREAM_PATH = 'qick_216.bit'#'/path/to/your/firmware.bit' # <--- CHANGE THIS\n", + "soc = QickSoc(BITSTREAM_PATH)\n", + "soccfg = soc\n", + "\n", + "# Define channel constants (adjust based on your firmware configuration)\n", + "FSGEN_CH = 0 # Full-speed generator (single tone, max bandwidth)\n", + "INTGEN_CH = [1, 2] # Interpolated generator (fine frequency resolution)\n", + "FSMUXGEN_CH = 3 # Full-speed mux generator (8 tones, phase coherent, up to 10 Gsps)\n", + "MIXMUXGEN_CH = 4 # Mixer-mux generator (8 tones, phase coherent, up to 7 Gsps, better SFDR)\n", + "\n", + "DYNRO_CH = 0 # Dynamically configured readout (axis_dyn_readout_v1)\n", + "FASTDYNRO_CH = 1 # Fast dynamic readout (axis_readout_v3, for phase-reset applications)\n", + "MUXRO_CH = [2, 3, 4, 5] # Muxed readout channels (PFB, 4 outputs used here)\n", + "STDRO_CH = 6 # Standard readout (axis_readout_v2, PYNQ-configured)\n", + "\n", + "print(\"Connected to QICK board\")\n", + "\n", + "print(f\"Available generators (DACs): {list(range(len(soccfg['gens'])))}\")\n", + "print(f\"Available readouts (ADCs): {list(range(len(soccfg['readouts'])))}\")\n", + "\n", + "print(f\"tProc core version: {soccfg['tprocs'][0]['version']}\")\n", + "print(f\"Sofware version: {soccfg['sw_version']}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== Readouts (ADCs) Hardware Identification ===\n", + "RO 0:\n", + " - Readout Type: axis_dyn_readout_v1 (v1.0)\n", + " - Buffer Type: axis_avg_buffer\n", + " - Decimation: 1\n", + " - Sampling Freq: 2457.6 MHz\n", + "------------------------------\n", + "RO 1:\n", + " - Readout Type: axis_readout_v3 (v1.0)\n", + " - Buffer Type: axis_avg_buffer\n", + " - Decimation: 1\n", + " - Sampling Freq: 2457.6 MHz\n", + "------------------------------\n", + "RO 2:\n", + " - Readout Type: axis_pfb_readout_v3 (v1.0)\n", + " - Buffer Type: axis_avg_buffer\n", + " - Decimation: 2\n", + " - Sampling Freq: 2457.6 MHz\n", + "------------------------------\n", + "RO 3:\n", + " - Readout Type: axis_pfb_readout_v3 (v1.0)\n", + " - Buffer Type: axis_avg_buffer\n", + " - Decimation: 2\n", + " - Sampling Freq: 2457.6 MHz\n", + "------------------------------\n", + "RO 4:\n", + " - Readout Type: axis_pfb_readout_v3 (v1.0)\n", + " - Buffer Type: axis_avg_buffer\n", + " - Decimation: 2\n", + " - Sampling Freq: 2457.6 MHz\n", + "------------------------------\n", + "RO 5:\n", + " - Readout Type: axis_pfb_readout_v3 (v1.0)\n", + " - Buffer Type: axis_avg_buffer\n", + " - Decimation: 2\n", + " - Sampling Freq: 2457.6 MHz\n", + "------------------------------\n", + "RO 6:\n", + " - Readout Type: axis_readout_v2 (v1.0)\n", + " - Buffer Type: axis_avg_buffer\n", + " - Decimation: 1\n", + " - Sampling Freq: 2457.6 MHz\n", + "------------------------------\n" + ] + } + ], + "source": [ + "print(\"=== Readouts (ADCs) Hardware Identification ===\")\n", + "for i, ro in enumerate(soccfg['readouts']):\n", + " ro_kind = ro.get('ro_type', 'Unknown RO')\n", + " buf_kind = ro.get('avgbuf_type', 'Unknown Buffer')\n", + " ro_ver = ro.get('ro_version', 'N/A')\n", + " \n", + " print(f\"RO {i}:\")\n", + " print(f\" - Readout Type: {ro_kind} (v{ro_ver})\")\n", + " print(f\" - Buffer Type: {buf_kind}\")\n", + " print(f\" - Decimation: {ro.get('decimation', 'N/A')}\")\n", + " print(f\" - Sampling Freq: {ro.get('fs', 'N/A')} MHz\")\n", + " print(\"-\" * 30)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Generator and Readout Types Overview\n", + "\n", + "Understanding the different generator and readout types is crucial for optimal performance." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════╗\n", + "║ GENERATOR TYPES ║\n", + "╠════════════════════════╦═════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ Generator Type ║ Best For ║\n", + "╠════════════════════════╬═════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ Full-Speed (FS) ║ Single tone, maximum bandwidth (10 Gsps), simple pulses ║\n", + "║ Interpolated (INT) ║ Fine frequency resolution, needs mixer_freq for upconversion, shaped pulses ║\n", + "║ Full-Speed Mux (FSMUX) ║ Multi-tone, phase-coherent, up to 8 tones @ 10 Gsps, constant envelope ║\n", + "║ Mixer-Mux (MIXMUX) ║ Multi-tone, phase-coherent, lower sample rate (7 Gsps), better SFDR ║\n", + "╠════════════════════════╩═════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ READOUT TYPES ║\n", + "╠════════════════════════╦═════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ Readout Type ║ Best For ║\n", + "╠════════════════════════╬═════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ Standard (STD) ║ Fixed frequency readout, simple averaging ║\n", + "║ Dynamic (DYN) ║ Sweeping frequencies, resonator spectroscopy, delay calibration ║\n", + "║ Fast Dynamic (FASTDYN) ║ Phase-reset applications, fast sequencing, qubit readout ║\n", + "║ Muxed PFB (MUX) ║ Multi-tone readout, 64 channels, simultaneous demodulation ║\n", + "╚════════════════════════╩═════════════════════════════════════════════════════════════════════════════════════╝\n", + "\n" + ] + } + ], + "source": [ + "print(\"\"\"\n", + "╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════╗\n", + "║ GENERATOR TYPES ║\n", + "╠════════════════════════╦═════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ Generator Type ║ Best For ║\n", + "╠════════════════════════╬═════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ Full-Speed (FS) ║ Single tone, maximum bandwidth (10 Gsps), simple pulses ║\n", + "║ Interpolated (INT) ║ Fine frequency resolution, needs mixer_freq for upconversion, shaped pulses ║\n", + "║ Full-Speed Mux (FSMUX) ║ Multi-tone, phase-coherent, up to 8 tones @ 10 Gsps, constant envelope ║\n", + "║ Mixer-Mux (MIXMUX) ║ Multi-tone, phase-coherent, lower sample rate (7 Gsps), better SFDR ║\n", + "╠════════════════════════╩═════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ READOUT TYPES ║\n", + "╠════════════════════════╦═════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ Readout Type ║ Best For ║\n", + "╠════════════════════════╬═════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ Standard (STD) ║ Fixed frequency readout, simple averaging ║\n", + "║ Dynamic (DYN) ║ Sweeping frequencies, resonator spectroscopy, delay calibration ║\n", + "║ Fast Dynamic (FASTDYN) ║ Phase-reset applications, fast sequencing, qubit readout ║\n", + "║ Muxed PFB (MUX) ║ Multi-tone readout, 64 channels, simultaneous demodulation ║\n", + "╚════════════════════════╩═════════════════════════════════════════════════════════════════════════════════════╝\n", + "\"\"\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Muxed Generators and Muxed Readouts (PFB)\n", + "\n", + "Muxed generators allow you to play multiple tones simultaneously, and muxed readouts (PFB) can demodulate them efficiently.\n", + "\n", + "**Key concepts:**\n", + "- The `mask` parameter in `add_pulse` selects which tones are played\n", + "- The PFB readout provides finer channel spacing than standard muxed readout (64 slices vs 8)\n", + "- Linking generators to readouts with `gen_ch` enables automatic frequency matching" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running muxed generator with PFB readout...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "4e9e81cc098a4242b9175f40122dbef9", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/1 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "class MuxProgram(AveragerProgramV2):\n", + " \"\"\"\n", + " Program demonstrating muxed generator with PFB readout.\n", + " Plays multiple tones simultaneously on a single DAC channel.\n", + " \"\"\"\n", + " def _initialize(self, cfg):\n", + " ro_chs = cfg['ro_chs']\n", + " gen_ch = cfg['gen_ch']\n", + " \n", + " # Declare a muxed generator with multiple tones\n", + " # The 'ro_ch' argument links it to a readout for frequency matching\n", + " self.declare_gen(ch=gen_ch, nqz=1, ro_ch=ro_chs[0],\n", + " mixer_freq=cfg['mixer_freq'],\n", + " mux_freqs=cfg['pulse_freqs'], \n", + " mux_gains=cfg['pulse_gains'], \n", + " mux_phases=cfg['pulse_phases'])\n", + " \n", + " # Declare each PFB readout channel, linking back to the same generator\n", + " # This automatically matches readout frequencies to generator tones\n", + " for ch, f, ph in zip(cfg['ro_chs'], cfg['pulse_freqs'], cfg['ro_phases']):\n", + " self.declare_readout(ch=ch, length=cfg['ro_len'], freq=f, phase=ph, gen_ch=gen_ch)\n", + "\n", + " # Create a constant pulse that plays on all 4 tones simultaneously\n", + " # The 'mask' parameter selects which tone indices to enable\n", + " self.add_pulse(ch=gen_ch, name=\"mymux\", \n", + " style=\"const\", \n", + " length=cfg[\"pulse_len\"],\n", + " mask=[0, 1, 2, 3],\n", + " )\n", + " \n", + " def _body(self, cfg):\n", + " # Trigger readouts to start taking data before the pulse\n", + " self.trigger(ros=cfg['ro_chs'], pins=[0], t=cfg['trig_time'], ddr4=True)\n", + " # Play the pulse\n", + " self.pulse(ch=cfg['gen_ch'], name=\"mymux\", t=0)\n", + " \n", + "# Configuration for the program\n", + "config_mux = {\n", + " 'gen_ch': MIXMUXGEN_CH, # we can use FSMUXGEN_CH here if we want higher sample rate but worse SFDR\n", + " 'ro_chs': MUXRO_CH,\n", + " 'mixer_freq': 500,\n", + " 'pulse_freqs': [500, 550, 600, 650], # MHz\n", + " 'pulse_gains': [1.0] * 4,\n", + " 'pulse_phases': [0.0] * 4,\n", + " 'ro_phases': [0.0] * 4, # Initial downconversion phases\n", + " 'trig_time': 0.4, # µs, trigger before pulse\n", + " 'pulse_len': 1.0, # µs\n", + " 'ro_len': 1.9, # µs, readout length\n", + "}\n", + "\n", + "print(\"Running muxed generator with PFB readout...\")\n", + "prog = MuxProgram(soccfg, reps=1, final_delay=0.5, cfg=config_mux)\n", + "iq_list = prog.acquire_decimated(soc, rounds=1)\n", + "t = prog.get_time_axis(ro_index=0)\n", + "\n", + "# Plot results for each readout channel\n", + "fig, axes = plt.subplots(len(config_mux['ro_chs']), 1, figsize=(12, 12))\n", + "for i, ch in enumerate(config_mux['ro_chs']):\n", + " axes[i].plot(t, iq_list[i][:, 0], label=\"I\")\n", + " axes[i].plot(t, iq_list[i][:, 1], label=\"Q\")\n", + " axes[i].plot(t, np.abs(iq_list[i].dot([1, 1j])), label=\"Magnitude\")\n", + " axes[i].legend()\n", + " axes[i].set_ylabel(f\"Tone {i} ({config_mux['pulse_freqs'][i]} MHz)\")\n", + " axes[i].set_xlabel(\"Time (µs)\")\n", + "plt.suptitle(\"Muxed Generator with PFB Readout\")\n", + "plt.tight_layout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.1 Correcting IQ Phase Offsets\n", + "\n", + "The raw IQ data is rotated due to cable delays and mixer imperfections. We can correct this by measuring the average phase and applying a correction to either the upconversion (pulse) phase or the downconversion (readout) phase." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Phase offsets: [-83.12613786622823, -130.43998631084776, 60.805937906847866, 15.380139289356636]\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "04e0d5bd756c4cf69aa97fe052e88ef5", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/1 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Calculate average phase offset for each channel (in degrees)\n", + "phases = [np.angle(iq.mean(axis=0).dot([1, 1j]), deg=True) for iq in iq_list]\n", + "print(f\"Phase offsets: {phases}\")\n", + "\n", + "# Option 1: Rotate the upconversion phase\n", + "config_mux['pulse_phases'] = [-x for x in phases]\n", + "prog = MuxProgram(soccfg, reps=1, final_delay=0.5, cfg=config_mux)\n", + "iq_list_corrected_up = prog.acquire_decimated(soc, rounds=1)\n", + "\n", + "# Option 2: Rotate the downconversion phase\n", + "config_mux['pulse_phases'] = [0.0] * 4\n", + "config_mux['ro_phases'] = phases\n", + "prog = MuxProgram(soccfg, reps=1, final_delay=0.5, cfg=config_mux)\n", + "iq_list_corrected_down = prog.acquire_decimated(soc, rounds=1)\n", + "\n", + "# Plot corrected data (Option 2 as example)\n", + "fig, axes = plt.subplots(len(config_mux['ro_chs']), 1, figsize=(12, 10))\n", + "for i, ch in enumerate(config_mux['ro_chs']):\n", + " axes[i].plot(t, iq_list_corrected_down[i][:, 0], label=\"I\")\n", + " axes[i].plot(t, iq_list_corrected_down[i][:, 1], label=\"Q\")\n", + " axes[i].plot(t, np.abs(iq_list_corrected_down[i].dot([1, 1j])), label=\"Magnitude\")\n", + " axes[i].legend()\n", + " axes[i].set_ylabel(f\"Tone {i} (Phase-corrected)\")\n", + " axes[i].set_xlabel(\"Time (µs)\")\n", + "plt.suptitle(\"Phase-Corrected Muxed Readout\")\n", + "plt.tight_layout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2 Mixer-Mux Generator Example\n", + "\n", + "The mixer-mux generator uses a digital mixer-based architecture that provides better SFDR at the cost of lower sample rate." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running mixer-mux generator...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "3eb0ce4ba3c74f5e89df147ca29a732a", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/1 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Using the same MuxProgram class with mixer-mux generator\n", + "config_mixmux = {\n", + " 'gen_ch': MIXMUXGEN_CH,\n", + " 'ro_chs': MUXRO_CH,\n", + " 'mixer_freq': 500,\n", + " 'pulse_freqs': [60, 100, 150, 400], # MHz (lower frequencies work better)\n", + " 'pulse_gains': [0.8] * 4, # Slightly lower gain for better linearity\n", + " 'pulse_phases': [0.0] * 4,\n", + " 'ro_phases': [0.0] * 4,\n", + " 'trig_time': 0.4,\n", + " 'pulse_len': 1.0,\n", + " 'ro_len': 1.9,\n", + "}\n", + "\n", + "print(\"Running mixer-mux generator...\")\n", + "prog_mixmux = MuxProgram(soccfg, reps=1, final_delay=0.5, cfg=config_mixmux)\n", + "iq_list_mixmux = prog_mixmux.acquire_decimated(soc, rounds=1)\n", + "\n", + "# Plot results\n", + "fig, axes = plt.subplots(len(config_mixmux['ro_chs']), 1, figsize=(12, 10))\n", + "for i in range(len(config_mixmux['ro_chs'])):\n", + " axes[i].plot(t, np.abs(iq_list_mixmux[i].dot([1, 1j])), label=f\"Channel {i}\")\n", + " axes[i].set_ylabel(f\"Magnitude (Tone {i})\")\n", + " axes[i].set_xlabel(\"Time (µs)\")\n", + " axes[i].legend()\n", + "plt.suptitle(\"Mixer-Mux Generator Performance\")\n", + "plt.tight_layout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.3 Playing Different Tone Combinations\n", + "\n", + "You can selectively enable tones using different masks." + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running selective tone playback...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "4aedf65f9fff4bae80630d1a19656083", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/1 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "class MuxProgramSelective(AveragerProgramV2):\n", + " \"\"\"Program demonstrating selective tone playback using masks.\"\"\"\n", + " \n", + " def _initialize(self, cfg):\n", + " ro_chs = cfg['ro_chs']\n", + " gen_ch = cfg['gen_ch']\n", + " \n", + " self.declare_gen(ch=gen_ch, nqz=1, ro_ch=ro_chs[0],\n", + " mixer_freq=cfg['mixer_freq'],\n", + " mux_freqs=cfg['pulse_freqs'], \n", + " mux_gains=cfg['pulse_gains'], \n", + " mux_phases=cfg['pulse_phases'])\n", + " \n", + " for ch, f, ph in zip(cfg['ro_chs'], cfg['pulse_freqs'], cfg['ro_phases']):\n", + " self.declare_readout(ch=ch, length=cfg['ro_len'], freq=f, phase=ph, gen_ch=gen_ch)\n", + "\n", + " # Add multiple pulses with different masks\n", + " self.add_pulse(ch=gen_ch, name=\"tones_even\", \n", + " style=\"const\", length=cfg[\"pulse_len\"],\n", + " mask=[0, 2]) # Even-indexed tones\n", + " \n", + " self.add_pulse(ch=gen_ch, name=\"tones_odd\", \n", + " style=\"const\", length=cfg[\"pulse_len\"],\n", + " mask=[1, 3]) # Odd-indexed tones\n", + " \n", + " def _body(self, cfg):\n", + " self.trigger(ros=cfg['ro_chs'], pins=[0], t=cfg['trig_time'], ddr4=True)\n", + " # First pulse\n", + " self.pulse(ch=cfg['gen_ch'], name=\"tones_even\", t=0)\n", + " # Second pulse starts after first finishes\n", + " self.pulse(ch=cfg['gen_ch'], name=\"tones_odd\", t=cfg['pulse_len'] + 0.1)\n", + "\n", + "config_selective = {\n", + " 'gen_ch': MIXMUXGEN_CH, # we can use FSMUXGEN_CH here if we want higher sample rate but worse SFDR\n", + " 'ro_chs': MUXRO_CH[:4],\n", + " 'mixer_freq': 500,\n", + " 'pulse_freqs': [50, 150, 200, 350],\n", + " 'pulse_gains': [1.0] * 4,\n", + " 'pulse_phases': [0.0] * 4,\n", + " 'ro_phases': [0.0] * 4,\n", + " 'trig_time': 0.4,\n", + " 'pulse_len': 1.0,\n", + " 'ro_len': 2.5,\n", + "}\n", + "\n", + "print(\"Running selective tone playback...\")\n", + "prog_selective = MuxProgramSelective(soccfg, reps=1, final_delay=0.5, cfg=config_selective)\n", + "iq_list_selective = prog_selective.acquire_decimated(soc, rounds=1)\n", + "\n", + "npts = iq_list_selective[0].shape[0]\n", + "t = np.linspace(0, config_selective['ro_len'], npts)\n", + "\n", + "# Plot showing two pulse sequences\n", + "npts = iq_list_selective[0].shape[0]\n", + "t = np.linspace(0, config_selective['ro_len'], npts)\n", + "\n", + "fig, axes = plt.subplots(2, 1, figsize=(12, 10))\n", + "\n", + "for i, ch in enumerate(config_selective['ro_chs']):\n", + " mag = np.abs(iq_list_selective[i].dot([1, 1j]))\n", + " axes[0].plot(t, mag, label=f\"Tone {i} ({config_selective['pulse_freqs'][i]} MHz)\")\n", + "\n", + "axes[0].set_ylabel(\"Magnitude\")\n", + "axes[0].set_xlabel(\"Time (µs)\")\n", + "axes[0].legend()\n", + "axes[0].set_title(\"Selective Tone Playback: Even tones first, then odd tones\")\n", + "axes[0].grid(True)\n", + "\n", + "for i in range(4):\n", + " mag = np.abs(iq_list_selective[i].dot([1, 1j]))\n", + " axes[1].plot(t, mag, label=f\"Tone {i}\")\n", + "\n", + "axes[1].set_ylabel(\"Magnitude\")\n", + "axes[1].set_xlabel(\"Time (µs)\")\n", + "axes[1].legend()\n", + "axes[1].set_title(\"Individual Tone Responses\")\n", + "axes[1].grid(True)\n", + "\n", + "plt.tight_layout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Interpolated Generator and Standard Readout\n", + "\n", + "The interpolated generator uses a digital mixer to upconvert an IF signal. \n", + "\n", + "### Frequency Matching in tProc v2 vs. tProc v1\n", + "\n", + "| Aspect | tProc v1 | tProc v2 |\n", + "|--------|----------|----------|\n", + "| Frequency specification | IF (intermediate frequency) | Absolute frequency |\n", + "| Mixer frequency handling | User must add to both gen and readout | Automatic |\n", + "| Common point of confusion | Forgetting to account for mixer | None (automatic) |\n", + "\n", + "In tProc v2, you specify the **absolute** frequency you want to play. The software automatically calculates the correct IF by subtracting the mixer frequency. The readout frequency is also absolute." + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running interpolated generator with parameter sweeps...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "5a71a774629346ed9e15f6a93e995ab3", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/1 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "class SimpleSweepProgram(AveragerProgramV2):\n", + " \"\"\"\n", + " Program demonstrating interpolated generator with parameter sweeps.\n", + " Sweeps phase and gain simultaneously across multiple steps.\n", + " \"\"\"\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " \n", + " # Declare an interpolated generator with a mixer frequency\n", + " self.declare_gen(ch=gen_ch, nqz=1, ro_ch=ro_ch, mixer_freq=cfg['mixer_freq'])\n", + " \n", + " # Declare a standard readout (frequency is absolute)\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'], freq=cfg['freq'], gen_ch=gen_ch)\n", + "\n", + " # Add a loop for sweeping parameters\n", + " self.add_loop(\"myloop\", self.cfg[\"steps\"])\n", + "\n", + " # Create a flat-top pulse with Gaussian ramps\n", + " self.add_gauss(ch=gen_ch, name=\"ramp\", sigma=cfg['ramp_len']/10, \n", + " length=cfg['ramp_len'], even_length=True)\n", + " self.add_pulse(ch=gen_ch, name=\"mypulse\", ro_ch=ro_ch, \n", + " style=\"flat_top\", envelope=\"ramp\", \n", + " freq=cfg['freq'], length=cfg['flat_len'],\n", + " phase=cfg['phase'], gain=cfg['gain'])\n", + " \n", + " def _body(self, cfg):\n", + " self.pulse(ch=cfg['gen_ch'], name=\"mypulse\", t=0)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'])\n", + "\n", + "# Configuration\n", + "config_sweep = {\n", + " 'steps': 5,\n", + " 'gen_ch': INTGEN_CH[0],\n", + " 'ro_ch': STDRO_CH,\n", + " 'freq': 2000, # Absolute frequency (MHz)\n", + " 'mixer_freq': 1500, # Mixer frequency (MHz)\n", + " 'trig_time': 0.45, # µs\n", + " 'ro_len': 0.3, # µs\n", + " 'flat_len': 0.05, # µs\n", + " 'ramp_len': 0.2, # µs (total pulse length is flat_len + ramp_len)\n", + " 'phase': QickSweep1D(\"myloop\", -360, 720), # Sweep phase from -360° to 720°\n", + " 'gain': QickSweep1D(\"myloop\", 0.0, 1.0) # Sweep gain from 0 to 1\n", + "}\n", + "\n", + "print(\"Running interpolated generator with parameter sweeps...\")\n", + "prog = SimpleSweepProgram(soccfg, reps=1, final_delay=0.5, cfg=config_sweep)\n", + "iq_list = prog.acquire_decimated(soc, rounds=1)\n", + "t = prog.get_time_axis(ro_index=0)\n", + "\n", + "# Plot results\n", + "plt.figure(figsize=(12, 6))\n", + "for ii, iq in enumerate(iq_list[0]):\n", + " plt.plot(t, iq[:, 0], label=f\"I value, step {ii}\")\n", + "plt.legend()\n", + "plt.ylabel(\"Amplitude\")\n", + "plt.xlabel(\"Time (µs)\")\n", + "plt.title(\"Swept Phase and Gain with Interpolated Generator\")\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Full-Speed Generator and Dynamically Configured Readout\n", + "\n", + "Dynamically configured readouts allow you to change parameters (like frequency) during a sweep. This is essential for resonator spectroscopy and electrical delay calibration.\n", + "\n", + "**Key steps:**\n", + "1. Define a readout configuration using `add_readoutconfig()`\n", + "2. Send the configuration using `send_readoutconfig()` before it takes effect\n", + "3. For sweeps, send the new configuration in the `exec_before` block of the loop" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running dynamic frequency sweep...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "8c845cef52394218acd21f18f1e10101", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/50 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "class DynamicFreqSweepProgram(AveragerProgramV2):\n", + " \"\"\"\n", + " Program demonstrating dynamic readout configuration for frequency sweeps.\n", + " Used for electrical delay calibration and resonator characterization.\n", + " \"\"\"\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " \n", + " self.declare_gen(ch=gen_ch, nqz=cfg['nqz'])\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'])\n", + "\n", + " # Define the readout configuration (like a pulse for the readout)\n", + " self.add_readoutconfig(ch=ro_ch, name=\"myro\", freq=cfg['freq'], gen_ch=gen_ch)\n", + " \n", + " # The exec_before block runs before each loop iteration\n", + " # We use it to send the updated readout config\n", + " loopbefore = AsmV2()\n", + " loopbefore.send_readoutconfig(ch=cfg['ro_ch'], name=\"myro\", t=0)\n", + " self.add_loop(\"myloop\", self.cfg[\"steps\"], exec_before=loopbefore)\n", + "\n", + " self.add_gauss(ch=gen_ch, name=\"ramp\", sigma=cfg['ramp_len']/10, \n", + " length=cfg['ramp_len'], even_length=True)\n", + " self.add_pulse(ch=gen_ch, name=\"mypulse\", ro_ch=ro_ch, \n", + " style=\"flat_top\", envelope=\"ramp\", \n", + " freq=cfg['freq'], length=cfg['flat_len'],\n", + " phase=cfg['phase'], gain=cfg['gain'])\n", + " \n", + " def _body(self, cfg):\n", + " self.pulse(ch=cfg['gen_ch'], name=\"mypulse\", t=0)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'])\n", + "\n", + "# Small frequency sweep to see phase rotation\n", + "START_FREQ = 100\n", + "CAL_RANGE = 1\n", + "\n", + "config_dyn = {\n", + " 'steps': 5,\n", + " 'gen_ch': FSGEN_CH,\n", + " 'ro_ch': DYNRO_CH,\n", + " 'freq': QickSweep1D(\"myloop\", START_FREQ, START_FREQ + CAL_RANGE),\n", + " 'nqz': 1,\n", + " 'trig_time': 0.4, # µs\n", + " 'ro_len': 0.3, # µs\n", + " 'flat_len': 0.05, # µs\n", + " 'ramp_len': 0.2, # µs\n", + " 'phase': 0,\n", + " 'gain': 1.0\n", + "}\n", + "\n", + "print(\"Running dynamic frequency sweep...\")\n", + "prog = DynamicFreqSweepProgram(soccfg, reps=10, final_delay=0.5, cfg=config_dyn)\n", + "iq_list = prog.acquire(soc, rounds=1)\n", + "freqs = prog.get_pulse_param('myro', 'freq', as_array=True)\n", + "\n", + "# The IQ vector rotates as frequency changes due to electrical delay\n", + "plt.figure(figsize=(8, 8))\n", + "plt.plot(iq_list[0][0][:, 0], iq_list[0][0][:, 1], '.-', markersize=10)\n", + "plt.ylabel(\"Q\")\n", + "plt.xlabel(\"I\")\n", + "plt.title(\"Phase Rotation from Small Frequency Sweep\")\n", + "plt.axis('equal')\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 5.1 Electrical Delay Calibration\n", + "\n", + "The phase rotation we observe is due to the electrical delay between the DAC and ADC. By measuring the slope of phase vs. frequency, we can calculate this delay and correct for it." + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Performing frequency sweep for delay calibration...\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "9c431a2815a0470fbb8e77232387f3d9", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/100100 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "

      " + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Perform a wide-range sweep for calibration\n", + "END_FREQ = 8000 # MHz\n", + "config_dyn['freq'] = QickSweep1D(\"myloop\", START_FREQ, END_FREQ)\n", + "config_dyn['steps'] = 1001 # Number of frequency points\n", + "\n", + "print(\"Performing frequency sweep for delay calibration...\")\n", + "prog = DynamicFreqSweepProgram(soccfg, reps=100, final_delay=1.0, cfg=config_dyn)\n", + "freqs = prog.get_pulse_param('myro', 'freq', as_array=True)\n", + "\n", + "# Acquire data with progress bar\n", + "start_time = time.time()\n", + "iq_list = prog.acquire(soc, rounds=1, progress=True)\n", + "iq_complex = iq_list[0][0].dot([1, 1j])\n", + "print(f\"Sweep completed in {time.time() - start_time:.2f} seconds\")\n", + "\n", + "# Measure the phase slope (electrical delay)\n", + "phases = np.unwrap(np.angle(iq_complex)) / (2 * np.pi)\n", + "a = np.vstack([freqs, np.ones_like(freqs)]).T\n", + "phase_delay = np.linalg.lstsq(a, phases, rcond=None)[0][0]\n", + "print(f\"Measured electrical delay: {phase_delay:.6f} µs\")\n", + "print(f\"This corresponds to {phase_delay * 1e3:.2f} ns of cable delay\")\n", + "\n", + "# Apply the correction\n", + "iq_rotated = iq_complex * np.exp(-1j * freqs * 2 * np.pi * phase_delay)\n", + "\n", + "# Plot the corrected IQ trajectory\n", + "plt.figure(figsize=(8, 8))\n", + "plt.plot(np.real(iq_rotated), np.imag(iq_rotated), '.')\n", + "plt.ylabel(\"Q\")\n", + "plt.xlabel(\"I\")\n", + "plt.title(\"Corrected IQ Trajectory (Flat Phase)\")\n", + "plt.axis('equal')\n", + "plt.grid(True)\n", + "plt.show()\n", + "\n", + "# Plot amplitude and phase of the corrected data\n", + "phases_corrected = np.unwrap(np.angle(iq_rotated)) / (2 * np.pi)\n", + "\n", + "fig, ax1 = plt.subplots(figsize=(12, 6))\n", + "ax1.semilogy(freqs, np.abs(iq_rotated), label=\"Amplitude\", color='blue')\n", + "ax1.set_ylabel(\"Amplitude\", color='blue')\n", + "ax1.set_xlabel(\"Frequency (MHz)\")\n", + "ax1.tick_params(axis='y', labelcolor='blue')\n", + "ax1.grid(True)\n", + "\n", + "ax2 = ax1.twinx()\n", + "ax2.plot(freqs, phases_corrected, color='red', label='Phase')\n", + "ax2.set_ylabel(\"Phase (cycles)\", color='red')\n", + "ax2.tick_params(axis='y', labelcolor='red')\n", + "\n", + "plt.title(\"Frequency Response After Delay Calibration\")\n", + "fig.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. Fast Dynamic Readout (Phase-Reset Applications)\n", + "\n", + "The fast dynamic readout (`axis_readout_v3`) is optimized for applications requiring rapid phase resets between measurements, such as qubit readout in quantum computing experiments. It allows changing readout parameters on every trigger without reconfiguring the entire readout chain." + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " def add_readoutconfig(self, ch, name, **kwargs):\n", + " \"\"\"Add a readout config to the program's pulse library.\n", + " The \"mode\" and \"length\" parameters have no useful effect and should probably never be used.\n", + "\n", + " Parameters\n", + " ----------\n", + " ch : int or list of int\n", + " Readout channel (index in 'readouts' list).\n", + " The use of one readoutconfig for multiple readouts is experimental.\n", + " The readouts must be of the same type and running at the same sampling frequency.\n", + " name : str\n", + " name of the config\n", + " freq : float or QickParam\n", + " Frequency (MHz)\n", + " phase : float or QickParam\n", + " Phase (degrees)\n", + " phrst : int\n", + " If 1, it resets the DDS phase. The default is 0.\n", + " mode : str\n", + " Selects whether the output is \"oneshot\" (the default) or \"periodic.\"\n", + " outsel : str\n", + " Selects the output source. The input is real, the output is complex. If \"product\" (the default), the output is the product of input and DDS. If \"dds\", the output is the DDS only. If \"input\", the output is from the input. If \"zero\", the output is always zero.\n", + " length : float or QickParam\n", + " The duration (us) of the config pulse. The default is the shortest possible length.\n", + " gen_ch : int\n", + " generator channel (use None if you don't want the downconversion frequency to be rounded to a valid DAC frequency or be offset by the DAC mixer frequency)\n", + " \"\"\"\n", + " if isinstance(ch, Number):\n", + " ch = [ch]\n", + " else: # list of channels\n", + " distinct_cfgs = len(set([self._ro_mgrs[x].cfg_hash for x in ch]))\n", + " if distinct_cfgs != 1:\n", + " raise RuntimeError(\"tried to define a pulse for generators %s, but they have different types or sampling freqs\"%(ch))\n", + " prog_chs = set(self.ro_chs.keys())\n", + " if set(ch) - prog_chs:\n", + " raise RuntimeError(\"readoutconfig %s is defined for readout(s) %s, but only readouts %s are declared\"%(name, ch, prog_chs))\n", + " pulse = self._ro_mgrs[ch[0]].make_pulse(kwargs)\n", + " pulse.ro_chs = [ch]\n", + " self._register_pulse(pulse, name)\n", + "\n" + ] + } + ], + "source": [ + "import inspect\n", + "from qick.qick_asm import AbsQickProgram\n", + "print(inspect.getsource(prog_fast.add_readoutconfig))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running fast dynamic readout test (frequency hopping)...\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "aa5c116b68a44245b75db86ee005b254", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/100 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "class FastDynamicReadoutProgram(AveragerProgramV2):\n", + " \"\"\"\n", + " Program demonstrating fast dynamic readout for rapid parameter changes.\n", + " Ideal for phase-reset applications and fast sequencing.\n", + " \"\"\"\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " \n", + " self.declare_gen(ch=gen_ch, nqz=cfg['nqz'])\n", + " \n", + " # declare_readout: length only, no sel/outsel/freq/phase\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'])\n", + " \n", + " # outsel goes here in add_readoutconfig only\n", + " for i, (freq, phase) in enumerate(zip(cfg['freqs'], cfg['phases'])):\n", + " self.add_readoutconfig(\n", + " ch=ro_ch,\n", + " name=f\"ro_conf_{i}\",\n", + " freq=freq,\n", + " phase=phase,\n", + " gen_ch=gen_ch,\n", + " outsel='input'\n", + " )\n", + " \n", + " self.add_gauss(ch=gen_ch, name=\"ramp\", sigma=cfg['ramp_len']/10,\n", + " length=cfg['ramp_len'], even_length=True)\n", + " \n", + " for i, (freq, phase) in enumerate(zip(cfg['freqs'], cfg['phases'])):\n", + " self.add_pulse(ch=gen_ch,\n", + " name=f\"pulse_{i}\",\n", + " ro_ch=ro_ch,\n", + " style=\"flat_top\",\n", + " envelope=\"ramp\",\n", + " freq=freq,\n", + " phase=phase,\n", + " length=cfg['flat_len'],\n", + " gain=cfg['gain']\n", + " )\n", + " \n", + " def _body(self, cfg):\n", + " t = 0 # running absolute time cursor\n", + " step_len = cfg['ro_len'] + 0.1 # readout window + small guard gap\n", + " \n", + " for i in range(cfg['num_steps']):\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=f\"ro_conf_{i}\", t=t)\n", + " self.pulse(ch=cfg['gen_ch'], name=f\"pulse_{i}\", t=t)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=t + cfg['trig_time'])\n", + " \n", + " # Advance time cursor past this step's readout window\n", + " self.delay_auto(t=0.1, tag=f\"step_{i}\") # let QICK resolve end of step\n", + " t += step_len # manually track for next pulse/trigger offset\n", + " \n", + "\n", + "# Example: Fast frequency hopping\n", + "config_fast = {\n", + " 'gen_ch': FSGEN_CH,\n", + " 'ro_ch': FASTDYNRO_CH,\n", + " 'nqz': 1,\n", + " 'freqs': [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000],\n", + " 'phases': [0] * 10,\n", + " 'gain': 0.5,\n", + " 'trig_time': 0.4,\n", + " 'ro_len': 5.0,\n", + " 'flat_len': 4.5,\n", + " 'ramp_len': 0.2,\n", + " 'num_steps': 10,\n", + " 'final_delay': 0.5, # per-step gap, passed to delay_auto\n", + "}\n", + "\n", + "print(\"Running fast dynamic readout test (frequency hopping)...\")\n", + "prog_fast = FastDynamicReadoutProgram(soccfg, reps=100, final_delay=0.5, cfg=config_fast)\n", + "iq_list_fast = prog_fast.acquire(soc, rounds=1, progress=True)\n", + "\n", + "iq_array = iq_list_fast[0] # shape (10, 2)\n", + "\n", + "magnitudes = np.abs(iq_array[:, 0] + 1j * iq_array[:, 1])\n", + "\n", + "# Plot results for each frequency\n", + "plt.figure(figsize=(8, 5))\n", + "plt.plot(config_fast['freqs'], magnitudes, 'o-')\n", + "plt.xlabel(\"Frequency (MHz)\")\n", + "plt.ylabel(\"Magnitude (averaged IQ)\")\n", + "plt.title(\"Fast Dynamic Readout - Frequency Hopping\")\n", + "plt.grid(True)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 7. Measuring IQ Offsets\n", + "\n", + "Some readout blocks (especially muxed ones) introduce a small, systematic DC offset. The `acquire()` and `acquire_decimated()` methods automatically subtract these offsets from the returned data. The raw data (without subtraction) can be accessed via `get_raw()`." + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Measuring IQ offsets...\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b49e458d22634c9099ecabe656a98d4f", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/1000 [00:00\n", + "ch 3 iq_offset: -0.5, type: \n", + "ch 4 iq_offset: -0.5, type: \n", + "ch 5 iq_offset: -0.5, type: \n", + "ch 6 iq_offset: 0.0, type: \n", + "\n", + "Note: The software automatically subtracts these hardware offsets from acquired data.\n", + "You can manually access raw data via prog.get_raw() if needed.\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1gAAAQwCAYAAAD4n/8RAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAD+SElEQVR4nOzde3xU1bn/8c9zgBIKiISgpQQNUvTgBQOigAHBKiJVgloROLbi0arYoq38asEbgtVWQRTxUg9FgQq1tWottmAjAkVaRcJptBWwiNgajMhV4SAg+Pz+mE06CZNkkrlm5vt+veY1M3vvtffaD5uVeWatvcbcHREREREREYndf6S6AiIiIiIiIplCCZaIiIiIiEicKMESERERERGJEyVYIiIiIiIicaIES0REREREJE6UYImIiIiIiMSJEiwREYnIzCaZ2bxU16M6M1tmZt9JdT2iZWZFZrbezHab2UVmdrSZLTezXWY2LdX1ExGR+FKCJSKSxczsv8ysNPjwX2Fmi8ysX6rr1VBmNtrMVpvZp2ZWbmZTzKxpDPurNZkzs3wzm29m28zs/8zsDTO7sNpmdwGPuHsrd38BuBbYChzh7v8vUXUTEZHUUIIlIpKlzGwcMB34CXA0cAzwGDAshdWK1ZeBHwB5QG/gHOCHiTiQmeUCK4D9wEnBMR8Efmlml4ZteizwdrX3a9zdE1EvERFJLSVYIiJZyMzaEOpZ+Z67P+/u/+fun7v7i+5+c9imXzKzXwTD2d42s15h+5hgZhuCdWvM7OKwdVea2Qozu9/MdpjZRjMbErZ+mZn92Mz+HJQvMbO8sPV9zOwvZrbTzN40s4HRnJe7/8zdX3X3/e6+CZgPFDU4ULW7CdgNXO3uH7n7Z+7+NHAPMM1CNgDHAS8GvYRPA6OBHwXvzzWzM4JexE/NbLOZPXDoADXFwczuAfoDjwT7eSRB5ygiIvWkBEtEJDv1BXKA39axXTHwK+BIYAEQ/kF+A6EP+W2AycA8M+sQtr438A6hnp0pwBNmZmHr/wv4b+Ao4EsEPU1m1hH4A3A3kBssf87M2tf3JIGzqNp7FE+DgOfc/Ytqy58h1Bt4vLt3Af4FDA2GCI4ilPRNCd4vBh4CHnL3I4AuQfla4+DutwGvAmOD/YxN0DmKiEg9KcESEclO7YCt7n6gju1WuPtCdz8IPAWcemiFu//G3T909y/c/dfAeuCMsLL/dPefB2XnAh0IDUU8ZLa7/8PdPyOUVBQGy78FLAyO+4W7vwyUAt+ozwma2X8DvYD761OuHvKAigjLK8LWR+Nz4Gtmlufuu9399WB5XOIgIiLJpQRLRCQ7bQPyopgA4qOw13uAnENlzOwKMysLhq/tBE6malJRWdbd9wQvW9Wy70PrjgWGH9pvsO9+hBK0qJjZRcC9wBB331rDNrcGw+t2m9nj0e47zNYa6tQhbH00rgaOB9aZ2aqwSTJijoOIiCRfg2dWEhGRRu01YC9wEfBsfQub2bHAzwlNIvGaux80szLAai0YnQ+Ap9z9moYUNrPzg7pd4O5/q2k7d/8JoQk+Gmox8E0zm1xtmOBlhM7hH9HsxN3XA6PM7D+AS4BnzawddcdBk2SIiKQh9WCJiGQhd/8EmAg8Gvw205fNrJmZDTGzKVHsoiWhD/hboHI43slxqt48YKiZDTazJmaWY2YDzSy/roJm9nVC9zh9093fiFN9avIgcAShe8u+EtRzFHAbcHO0swSa2beC+6q+AHYGiw9Sdxw2E5pAQ0RE0ogSLBGRLOXuDwDjgNsJJUofAGOBF6IouwaYRqgnbDNwCvDnONXrA0JTxd8aVq+bie5v1h2EJt1YGDb8b1E86hWhntsIDdnLAdYQGnY5Dvh2cE9atM4H3jaz3YQmvBjp7nujiMNDwKXBLI0z4nFOIiISO9PPcIiIiIiIiMSHerBERERERETiRAmWiIiIiIhInCjBEhERERERiRMlWCIiIiIiInGSFr+DlZeX5wUFBamuhoiIZJJPPgk9t2mT2nqIiEhGWr169VZ3b199eVokWAUFBZSWlqa6GiIiIiIiIlExs39GWq4hgiIikpneeSf0EBERSaK06MESERGJu+uuCz0vW5bSakjjcvWcVbWuf+LK05NUExFprNSDJSIiIiIiEifqwRIRERGRRunzzz+nvLycvXv3proqksFycnLIz8+nWbNmUW2vBEtERCTOMm2YWaadTyxqi0U2xSFdlJeX07p1awoKCjCzVFdHMpC7s23bNsrLy+ncuXNUZTREUEREREQapb1799KuXTslV5IwZka7du3q1UuqHiwREclMt99e5ybqjRBp/JRcSaLV9xpTgiUiIpnp3HNTXQMREclCGiIoIiKZqaws9BARSaBWrVpVeT9nzhzGjh0b0z4LCgrYunVrTPuIp3Xr1lFYWEiPHj3YsGEDM2bMoFu3blx++eX12s/OnTt57LHHGlSHuXPn0rVrV7p27crcuXMjbjNnzhzat29PYWEhhYWFzJo1q87yGzdupHfv3nTt2pURI0awf//+BtUvnBIsERHJTD/4QeghIpLGDhw4kPBjHDx4MKbyL7zwAsOGDeOvf/0rXbp04bHHHmPhwoXMnz+/XvtpaIK1fft2Jk+ezMqVK3njjTeYPHkyO3bsiLjtiBEjKCsro6ysjO985zt1lh8/fjw33XQT69evp23btjzxxBP1rl91GiIoIiKSRuqasa82um9MJL28+OKL3H333ezfv5927doxf/58jj76aCZNmsSHH37I+++/T15eHg8//DCjRo1iy5YtnHHGGbg7AFOmTCEnJ4cbb7yRm266iTfffJMlS5bwyiuvMHv2bObNm8f111/PqlWr+Oyzz7j00kuZPHkyEOoFu+qqqygpKWHs2LHk5uZy5513sm/fPrp06cLs2bMP630rKytjzJgx7Nmzhy5duvDkk0/y2muvMX36dJo0acLy5cs54YQTeO+99yguLuaqq66iZ8+efP/73wdC9yotX76c1q1bM3XqVJ555hn27dvHxRdfzOTJk5kwYQIbNmygsLCQQYMGMXXq1Kji+Mc//pFBgwaRm5sLwKBBg3jppZcYNWpUTOVHjhzJkiVL+OUvfwnA6NGjmTRpEtdff31U+62JEiwRERERyQwDBx6+7LLL4LvfhT174BvfOHz9lVeGHlu3wqWXVl23bFmdh/zss88oLCysfL99+3aKi4sB6NevH6+//jpmxqxZs5gyZQrTpk0DYPXq1axYsYIWLVpw44030q9fPyZOnMgf/vAHZs6cCcBZZ53FtGnTuPHGGyktLWXfvn18/vnnrFixgv79+wNwzz33kJuby8GDBznnnHN466236N69OxD6/aYVK1awdetWLrnkEhYvXkzLli257777eOCBB5g4cWKVc7niiit4+OGHGTBgABMnTmTy5MlMnz6dMWPG0KpVK374wx8C8NJLL7F06VLy8vIYOnQojz76KEVFRezevZucnBxKSkpYv349b7zxBu5OcXExy5cv59577+Xvf/87ZWHDtwsLC6u8j2TTpk106tSp8n1+fj6bNm2KuO1zzz3H8uXLOf7443nwwQfp1KlTjeW3bdvGkUceSdOmTevcb30owRIREZGYNLTXTT1u8aHZMFOrRYsWVRKEOXPmUFpaCoR+p2vEiBFUVFSwf//+Kr+jVFxcTIsWLQBYvnw5zz//PAAXXHABbdu2BeC0005j9erV7Nq1i+bNm9OzZ09KS0t59dVXmTFjBgDPPPMMM2fO5MCBA1RUVLBmzZrKBGvEiBEAvP7666xZs4aioiIA9u/fT9++faucxyeffMLOnTsZMGAAEOrNGT58eJ3nX1RUxLhx47j88su55JJLyM/Pp6SkhJKSEnr06AHA7t27Wb9+Pcccc8xh5etKroDKHr1wkWb2Gzp0KKNGjaJ58+Y8/vjjjB49miVLltRYPtr91pcSLBERERHJDLX1OH35y7Wvz8uLqseqPm644QbGjRtHcXExy5YtY9KkSZXrWrZsWWXbSB/smzVrRkFBAbNnz+bMM8+ke/fuLF26lA0bNtCtWzc2btzI/fffz6pVq2jbti1XXnllld9rOnQMd2fQoEE8/fTTcT0/gAkTJnDBBRewcOFC+vTpw+LFi3F3brnlFq677roq277//vtR7XPlypWVZe+66y7y8/NZFvZvU15ezsAIvZXt2rWrfH3NNdcwfvx4gBrL5+XlsXPnTg4cOEDTpk0pLy/nq1/9anQnXgslWCIikpl+8pNU16BRieXer3TU2Hp16op/OtZZ6vbJJ5/QsWNHgBpnvoPQUMD58+dz++23s2jRoioTOJx11lncf//9PPnkk5xyyimMGzeO0047DTPj008/pWXLlrRp04bNmzezaNGiiIlHnz59+N73vse7777L1772Nfbs2UN5eTnHH3985TZt2rShbdu2vPrqq/Tv35+nnnqqsjerNhs2bOCUU07hlFNO4bXXXmPdunUMHjyYO+64g8svv5xWrVqxadMmmjVrRuvWrdm1a1ed++zdu3eVnq3t27dz6623VsalpKSEn/70p4eVq6iooEOHDgAsWLCAbt26ATB48OCI5c2Ms88+m2effZaRI0cyd+5chg0bVmf96tLgBMvMOgG/AL4CfAHMdPeHzCwX+DVQALwPXObukaf5EBERSZQzz0x1DUQky02aNInhw4fTsWNH+vTpw8aNGyNud+eddzJq1Ch69uzJgAEDqgyl69+/P/fccw99+/alZcuW5OTkVN5/deqpp9KjRw9OOukkjjvuuMohgNW1b9+eOXPmMGrU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6wkNaTwVeD8o801gsLvXJ0bfBt43s0+BMYTuTcPdSwndh/UIoeGG7wJXhpX7KaGkcGf4zIMiIpJ8FvqyTkRERCIxs/OAp4Fz3L0sxdUREZE0pwRLRESkDmY2FOjo7pEmxhAREamkBEtERERERCROdA+WiIiIiIhInNT1WyhJkZeX5wUFBamuhoiIiIiISFRWr1691d0P+wH6tEiwCgoKKC0tTXU1REQkk7zzTuj5hBNSWw8REclIZvbPSMvTIsESERGJu+uuCz0vW5bSaoiISHZRgiUiIiKNztVzVtW6/okrT09STUREqtIkFyIiIiIiInGiHiwRERHJOLX1cKl3K3N8/vnnlJeXs3fv3lRXRTJYTk4O+fn5NGvWLKrtlWCJiIiISKNUXl5O69atKSgowMxSXR3JQO7Otm3bKC8vp3PnzlGVUYIlIiKZ6fbbU10DEUmwvXv3KrmShDIz2rVrx5YtW6IuowRLREQy07nnproGIpIESq4k0ep7jWmSCxERyUxlZaGHiIhIEinBEhGRzPSDH4QeIiIJ1KpVqyrv58yZw9ixY2PaZ0FBAVu3bo1pH/G0bt06CgsL6dGjBxs2bGDGjBl069aNyy+/vF772blzJ4899liD6jB37ly6du1K165dmTt3bsRt5syZQ/v27SksLKSwsJBZs2bVWX7jxo307t2brl27MmLECPbv39+g+oXTEEERERHRrHsiKXLgwAGaNk3sR/KDBw/SpEmTBpd/4YUXGDZsGJMnTwbgscceY9GiRVFP+nDIoQTru9/9br3Kbd++ncmTJ1NaWoqZcdppp1FcXEzbtm0P23bEiBE88sgjUZcfP348N910EyNHjmTMmDE88cQTXH/99fWqX3XqwRIRERERSYAXX3yR3r1706NHD84991w2b94MwKRJk7j22ms577zzuOKKK9i2bRvnnXcePXr04LrrrsPdAZgyZQozZswA4KabbuLrX/86AK+88grf+ta3ALj++uvp1asXJ510EnfeeWflsQsKCrjrrrvo168fv/nNbygpKaFv37707NmT4cOHs3v37sPqW1ZWRp8+fejevTsXX3wxO3bsYOHChUyfPp1Zs2Zx9tlnM2bMGN577z2Ki4t58MEH+dOf/lTZY9SjRw927doFwNSpUzn99NPp3r17Zb0mTJjAhg0bKCws5Oabb446jn/84x8ZNGgQubm5tG3blkGDBvHSSy/FXN7dWbJkCZdeeikAo0eP5oUXXoh6vzVRD5aIiEgjUVsvE6inSYSBAw9fdtll8N3vwp498I1vHL7+yitDj61bIfigXWnZsjoP+dlnn1FYWFj5fvv27RQXFwPQr18/Xn/9dcyMWbNmMWXKFKZNmwbA6tWrWbFiBS1atODGG2+kX79+TJw4kT/84Q/MnDkTgLPOOotp06Zx4403Ulpayr59+/j8889ZsWIF/fv3B+Cee+4hNzeXgwcPcs455/DWW2/RvXt3IPT7TStWrGDr1q1ccsklLF68mJYtW3LffffxwAMPMHHixCrncsUVV/Dwww8zYMAAJk6cyOTJk5k+fTpjxoyhVatW/PCHPwTgpZdeYunSpeTl5TF06FAeffRRioqK2L17Nzk5OZSUlLB+/XreeOMN3J3i4mKWL1/Ovffey9///nfKwu6PLSwsrPI+kk2bNtGpU6fK9/n5+WzatCnits899xzLly/n+OOP58EHH6RTp041lt+2bRtHHnlkZQ9ibfutDyVYIiIiIiIN1KJFiyoJwpw5cygtLQVCv9M1YsQIKioq2L9/f5UhdcXFxbRo0QKA5cuX8/zzzwNwwQUXVA59O+2001i9ejW7du2iefPm9OzZk9LSUl599dXKnq1nnnmGmTNncuDAASoqKlizZk1lgjVixAgAXn/9ddasWUNRUREA+/fvp2/fvlXO45NPPmHnzp0MGDAACPXmDB8+vM7zLyoqYty4cVx++eVccskl5OfnU1JSQklJCT169ABg9+7drF+/nmOOOeaw8nUlV0Blj164SDP7DR06lFGjRtG8eXMef/xxRo8ezZIlS2osH+1+60sJloiIZKaf/CTVNRB0b1c4xSIJautx+vKXa1+flxdVj1V93HDDDYwbN47i4mKWLVvGpEmTKte1bNmyyraRPtg3a9aMgoICZs+ezZlnnkn37t1ZunQpGzZsoFu3bmzcuJH777+fVatW0bZtW6688kr27t172DHcnUGDBvH000/H9fwgNOzvggsuYOHChfTp04fFixfj7txyyy1cd911VbZ9//33o9rnypUrK8vedddd5Ofnsyzs36a8vJyBEXor27VrV/n6mmuuYfz48QA1ls/Ly2Pnzp2V98GVl5fz1a9+NboTr4XuwRIRkcx05pmhh4hIinzyySd07NgRoMaZ7yA0FHD+/PkALFq0iB07dlRZd//993PWWWfRv39/Hn/8cQoLCzEzPv30U1q2bEmbNm3YvHkzixYtirj/Pn368Oc//5l3330XgD179vCPf/yjyjZt2rShbdu2vPrqqwA89dRTlb1ZtdmwYQOnnHIK48ePp1evXqxbt47Bgwfz5JNPVt7ntWnTJj7++GNat25deY9WbXr37k1ZWRllZWUUFxczePBgSkpK2LFjBzt27KCkpITBgwcfVq6ioqLy9YIFC+jWrRtAjeXNjLPPPptnn30WCP0bDRs2rM761UU9WCIikpn+8pfQs5IsoO77tyR2irFUN2nSJIYPH07Hjh3p06cPGzdujLjdnXfeyahRo+jZsycDBgyoMpSuf//+3HPPPfTt25eWLVuSk5NTef/VqaeeSo8ePTjppJM47rjjKocAVte+fXvmzJnDqFGj2LdvHwB33303xx9/fJXt5s6dy5gxY9izZw/HHXccs2fPrvMcp0+fztKlS2nSpAknnngiQ4YMoXnz5qxdu7ZyGGKrVq2YN28eXbp0oaioiJNPPpkhQ4YwderUqO7Bys3N5Y477uD000M9vRMnTiQ3N7fyda9evSguLmbGjBksWLCApk2bkpuby5w5c+osf9999zFy5Ehuv/12evTowdVXX13nOdfFIo09TLZevXr5obGqIiIicXFo+Eich/ykUiyTXMTy4T+W4WuJGhaXqvOpTTrWKdOtXbu2spdCJJEiXWtmttrde1XfVj1YIiIicZaq2f7UgyIiknq6B0tERERERCROGtyDZWadgF8AXwG+AGa6+0Nmlgv8GigA3gcuc/cdNe1HRESkLpp9LbUy7fe3NJQvs7h7XKbWFqlJfW+piqUH6wDw/9y9G9AH+J6ZnQhMAF5x967AK8F7EREREZG4ysnJYdu2bfX+ACwSLXdn27Zt5OTkRF2mwT1Y7l4BVASvd5nZWqAjMAwYGGw2F1gGjG/ocURERBpk+vRU10BipHvKpC75+fmUl5ezZcuWVFdFMlhOTg75+flRbx+XSS7MrADoAawEjg6SL9y9wsyOiscxRERE6qWwMNU1EJEEa9asGZ07d051NUSqiHmSCzNrBTwH/MDdP61HuWvNrNTMSvWtg4iIxN3ixaGHiIhIEsWUYJlZM0LJ1Xx3fz5YvNnMOgTrOwAfRyrr7jPdvZe792rfvn0s1RARETnc3XeHHiIiIkkUyyyCBjwBrHX3B8JWLQBGA/cGz7+LqYYiIiIZRvcWhSgOIpKJYrkHqwj4NvA3MysLlt1KKLF6xsyuBv4FDI+phiIiIiIiIo1ELLMIrgBq+tGBcxq6XxEREWlc1BOVvjLtN8xEGoO4zCIoIiIikg0SlUzGkggpwRVJL0qwREQkM/3P/6S6BiIikoWUYImISMol5Bv4E06I/z7DqNdAREQiifl3sERERNLSiy+GHiIiIkmkHiwRkSyTaTe913Q+N987if/8SmsYOrTeZaHxxUEyWzb1mOr/pTR26sESERERERGJE/VgiYgkUDZ9E5stPWMiUrdMaw9E6kM9WCIiIiIiInGiHiwRkQyk3peQdR/tYqpiIdIgieyFUhslmUwJloiIZKRZ10xOdRVERCQLKcESEUmRWL7B1f0LddvR7uhUV0Ek7cXSDqWiF0r3dkljoHuwREQkI52+8mVOX/lyqqshIiJZRj1YIiKSFMn+tnvg0ucAWNV7UFKPKyISLptmk5UQ9WCJiIiIiIjEiXqwRERERCTj6f4tSRb1YImIiIiIiMSJerBERBqhRN7PpN+nEZHGKlHtl+6jkvpQgiUiIhnpZ9+7N9VVEBGRLKQES0QaJNO+zcu08xHY3frIVFdBRBoR9d5LvOgeLBERyUhFK35P0Yrfp7oaIiKSZZRgiYhIRjpzxe85UwmWiIgkmRIsERERERGRONE9WCKSdJl2v5PG7YuISEPE8vejrr+Xmfa3tjFRD5aIiIiIiEicqAdLRLKCeplEREQSq66/tdnSc6YES0REMtJDN01PdRVERCQLKcESaeRi+baosY3P1jdjUh/7m+ekugoikgVSNUIiluNqVEdi6R4sERHJSGcveZazlzyb6mqIiEiWUQ+WSBpIZM9MY/uWSt/ISbz0emMxAEu/fmmKayIiItlEPVgiIiIiIiJxkrAeLDM7H3gIaALMcvd7E3UskUyXip4Z9Qb9m2IhIiKSWI3tvvDaJKQHy8yaAI8CQ4ATgVFmdmIijiUiIiIiIpIuEtWDdQbwrru/B2BmvwKGAWsSdDxJU7F8G5GqbzLUWxE7xVBERESqy5bPB+bu8d+p2aXA+e7+neD9t4He7j42bJtrgWuDtycA78S9IrHJA7amuhJZRjFPPsU8+RTz5FK8k08xTz7FPPkU8+RK13gf6+7tqy9MVA+WRVhWJZNz95nAzAQdP2ZmVuruvVJdj2yimCefYp58inlyKd7Jp5gnn2KefIp5cjW2eCdqFsFyoFPY+3zgwwQdS0REREREJC0kKsFaBXQ1s85m9iVgJLAgQccSERERERFJCwkZIujuB8xsLPBHQtO0P+nubyfiWAmUtsMXM5hinnyKefIp5smleCefYp58innyKebJ1ajinZBJLkRERERERLJRooYIioiIiIiIZB0lWCIiIiIiInGSdQmWmeWa2ctmtj54blvDdkea2bNmts7M1ppZ37rKm9ktZvaumb1jZoOTdU7prh4xf9/M/mZmZWZWGrb818GysmCbsmB5gZl9Frbu8SSdUlqLQ7wnmdmmsLh+I2ydrvEI4hDzqUFb85aZ/dbMjgyW6xqvQRxirra8nqKNebBtEzP7q5n9PmyZ2vJ6ikPM1Z7XQxzirba8nuIQ87Rsy7MuwQImAK+4e1fgleB9JA8BL7n7fwKnAmtrK29mJxKaLfEk4HzgMTNrkrCzaFyijTnA2e5eGP5bB+4+IlhWCDwHPB+2/YZD69x9TCIq3wjFFO/Ag2FxXQi6xusQa8xfBk529+7AP4BbwtbpGo8s1pirLa+/+sT8+/z77yagtryBYop5QO159GKNt9ry+os15mnZlmdjgjUMmBu8ngtcVH0DMzsCOAt4AsDd97v7zjrKDwN+5e773H0j8C5wRvyr3yjVGfNomJkBlwFPx6daGSsu8a5hv7rGI4sp5u5e4u4HgrevE/rtQKldrNe52vL6iyrmZpYPXADMqmG92vLoxSXmNexX1/nhYoq32vIGifUaT8u2PBsTrKPdvQIgeD4qwjbHAVuA2UFX5Cwza1lH+Y7AB2H7KA+WSXQxB3CgxMxWm9m1Edb3Bza7+/qwZZ2Df6M/mVn/+Fa70YpHvMcGQxyeDOtu1zVes3hd4wBXAYvC3usajyzWmKstr79oYz4d+BHwRQ3r1ZZHLx4xV3sevXhd46C2PFqxxjwt2/KE/A5WqpnZYuArEVbdFuUumgI9gRvcfaWZPUSoy/GO2g4bYVnWzIEfh5gDFLn7h2Z2FPCyma1z9+Vh60dR9RvPCuAYd99mZqcBL5jZSe7+ab1PoJFJcLx/BvyY0PX7Y2AaoT8UusYTfI2b2W3AAWB+sChrr3FIWrty2GEjLNN1HmXMzexC4GN3X21mA2vYTG15mATHXO15Ncm4xtWWV5WkduWwYhGWJe0az8gEy93PrWmdmW02sw7uXmFmHYCPI2xWDpS7+8rg/bP8e0xoTeXLgU5h+8gHPozpRBqROMQcd/8weP7YzH5LqCt3ebCPpsAlwGlh2+8D9gWvV5vZBuB4oJQMl8h4u/vmsH39HDh0M6mu8RrE6RofDVwInOMe+oHCbL7GIeExV1seQRxiXgQUW2gyhRzgCDOb5+7fCvahtryaRMZc7fnhknCNqy2vJsExT8u2PBuHCC4ARgevRwO/q76Bu38EfGBmJwSLzgHW1FF+ATDSzJqbWWegK/BG/KvfKNUZczNraWatD70GzgP+HrbJucA6dy8PK9PeghsWzew4QjF/LyFn0LjEFO+ggTrkYv7976BrvGaxxvx8YDxQ7O57wsroGq9ZrO2K2vL6i+bv5y3unu/uBYRuMF9y6INnQG15/cQUc7Xn9RZrvNWW11+s7Up6tuXunlUPoB2hWUbWB8+5wfKvAgvDtisk9M3CW8ALQNvaygfrbgM2AO8AQ1J9runyiCbmhO57ezN4vA3cVm0fc4Ax1ZZ9M9j2TeB/gaGpPtd0eMQab+Ap4G/Btb8A6BC2Ttd4YmL+LqGx4mXB4/Fgua7xxMVcbXkCYl5t+4HA76stU1uexJirPU96vNWWJz/madmWW1ABERERERERiVE2DhEUERERERFJCCVYIiIiIiIicaIES0REREREJE6UYImIiIiIiMSJEiwREREREZE4UYIlIiIiIiISJ0qwRERERERE4kQJloiIiIiISJwowRIREREREYkTJVgiIiIiIiJxogRLREREREQkTpRgiYiIiIiIxIkSLBERicjMJpnZvFTXozozW2Zm30l1PaJlZkVmtt7MdpvZRWZ2tJktN7NdZjYt1fUTEZH4UoIlIpLFzOy/zKw0+PBfYWaLzKxfquvVUGY20szeMbNPzOxjM5trZkfEsL9akzkzyzez+Wa2zcz+z8zeMLMLq212F/CIu7dy9xeAa4GtwBHu/v8SVTcREUkNJVgiIlnKzMYB04GfAEcDxwCPAcNSWK1Y/Rkocvc2wHFAU+DuRBzIzHKBFcB+4CQgD3gQ+KWZXRq26bHA29Xer3F3T0S9REQktZRgiYhkITNrQ6hn5Xvu/ry7/5+7f+7uL7r7zWGbfsnMfhEMZ3vbzHqF7WOCmW0I1q0xs4vD1l1pZivM7H4z22FmG81sSNj6ZWb2YzP7c1C+xMzywtb3MbO/mNlOM3vTzAZGc17u/oG7bw1bdBD4Wr0DFJ2bgN3A1e7+kbt/5u5PA/cA0yxkA6FE78Wgl/BpYDTwo+D9uWZ2RtCL+KmZbTazBw4doKY4mNk9QH/gkWA/jyToHEVEpJ6UYImIZKe+QA7w2zq2KwZ+BRwJLADCP8hvIPQhvw0wGZhnZh3C1vcG3iHUszMFeMLMLGz9fwH/DRwFfAn4IYCZdQT+QKjnKTdY/pyZtY/mxMysn5l9AuwCvkmoly4RBgHPufsX1ZY/Q6g38Hh37wL8CxgaDBEcBcwHpgTvFwMPAQ+5+xFAl6B8rXFw99uAV4GxwX7GJugcRUSknpRgiYhkp3bAVnc/UMd2K9x9obsfBJ4CTj20wt1/4+4fuvsX7v5rYD1wRljZf7r7z4Oyc4EOhIYiHjLb3f/h7p8RSioKg+XfAhYGx/3C3V8GSoFvRHNi7r4iGCKYD0wF3o+mXAPkARURlleErY/G58DXzCzP3Xe7++vB8pjiICIiqaEES0QkO20D8sysaR3bfRT2eg+Qc6iMmV1hZmXB8LWdwMlUTSoqy7r7nuBlq1r2fWjdscDwQ/sN9t2PUIIWNXffBLxEqAfuMGZ2azC8breZPV6ffQe21lCnDmHro3E1cDywzsxWhU2SEZc4iIhIctX1h1VERDLTa8Be4CLg2foWNrNjgZ8D5wCvuftBMysDrNaC0fkAeMrdr4nDvpoSGnZ3GHf/CaEJPhpqMfBNM5tcbZjgZYTO4R/R7MTd1wOjzOw/gEuAZ82sHXXHQZNkiIikIfVgiYhkIXf/BJgIPBr8NtOXzayZmQ0xsylR7KIloQ/4WwDM7L8J9WDFwzxgqJkNNrMmZpZjZgPNLL+ugmZ2uZkdE0wwcSyhCSdeiVO9qnsQOILQvWVfCeo5CrgNuDnaWQLN7FvBfVVfADuDxQepOw6bCU2gISIiaUQJlohIlnL3B4BxwO2EEqUPgLHAC1GUXQNMI9QTthk4hdAU6fGo1weEpoq/NaxeNxPd36wTgb8Qmt3vz4Qm2YhHT1ikem4jNGQvB1hDaNjlOODbwT1p0TofeNvMdhOa8GKku++NIg4PAZcGszTOiMc5iYhI7Ew/wyEiIiIiIhIf6sESERERERGJEyVYIiIiIiIicaIES0REREREJE6UYImIiIiIiMRJWvwOVl5enhcUFKS6GiIiIiIiIlFZvXr1VndvX315WiRYBQUFlJaWproaIiKSSd55J/R8wgmprYeIiGQkM/tnpOVpkWCJiIjE3XXXhZ6XLUtpNUREJLsowRIREREJXD1nVa3rn7jy9CTVREQaK01yISIiIiIiEifqwRIREYmzTOsFybTziUVtscimOKSLzz//nPLycvbu3ZvqqkgGy8nJIT8/n2bNmkW1vRIsEREREWmUysvLad26NQUFBZhZqqsjGcjd2bZtG+Xl5XTu3DmqMkqwREQkM91+e6prICIJtnfvXiVXklBmRrt27diyZUvUZZRgiYhIZjr33Do30XAvkcZPyZUkWn2vMU1yISIimamsLPQQERFJIiVYIiKSmX7wg9BDRCSBWrVqVeX9nDlzGDt2bEz7LCgoYOvWrTHtI57WrVtHYWEhPXr0YMOGDcyYMYNu3bpx+eWX12s/O3fu5LHHHmtQHebOnUvXrl3p2rUrc+fOjbjNnDlzaN++PYWFhRQWFjJr1qw6y2/cuJHevXvTtWtXRowYwf79+xtUv3BKsEREREREUuTAgQMJP8bBgwdjKv/CCy8wbNgw/vrXv9KlSxcee+wxFi5cyPz58+u1n4YmWNu3b2fy5MmsXLmSN954g8mTJ7Njx46I244YMYKysjLKysr4zne+U2f58ePHc9NNN7F+/Xratm3LE088Ue/6Vad7sERERNJIXVOi10b3jYmklxdffJG7776b/fv3065dO+bPn8/RRx/NpEmT+PDDD3n//ffJy8vj4YcfZtSoUWzZsoUzzjgDdwdgypQp5OTkcOONN3LTTTfx5ptvsmTJEl555RVmz57NvHnzuP7661m1ahWfffYZl156KZMnTwZCvWBXXXUVJSUljB07ltzcXO6880727dtHly5dmD179mG9b2VlZYwZM4Y9e/bQpUsXnnzySV577TWmT59OkyZNWL58OSeccALvvfcexcXFXHXVVfTs2ZPvf//7QOhepeXLl9O6dWumTp3KM888w759+7j44ouZPHkyEyZMYMOGDRQWFjJo0CCmTp0aVRz/+Mc/MmjQIHJzcwEYNGgQL730EqNGjYqp/MiRI1myZAm//OUvARg9ejSTJk3i+uuvj2q/NVGCJSIiIiKZYeDAw5dddhl897uwZw984xuHr7/yytBj61a49NKq65Ytq/OQn332GYWFhZXvt2/fTnFxMQD9+vXj9ddfx8yYNWsWU6ZMYdq0aQCsXr2aFStW0KJFC2688Ub69evHxIkT+cMf/sDMmTMBOOuss5g2bRo33ngjpaWl7Nu3j88//5wVK1bQv39/AO655x5yc3M5ePAg55xzDm+99Rbdu3cHQr/ftGLFCrZu3coll1zC4sWLadmyJffddx8PPPAAEydOrHIuV1xxBQ8//DADBgxg4sSJTJ48menTpzNmzBhatWrFD3/4QwBeeuklli5dSl5eHkOHDuXRRx+lqKiI3bt3k5OTQ0lJCevXr+eNN97A3SkuLmb58uXce++9/P3vf6cs7P7YwsLCKu8j2bRpE506dap8n5+fz6ZNmyJu+9xzz7F8+XKOP/54HnzwQTp16lRj+W3btnHkkUfStGnTOvdbH0qwREREJCYN7XVTj1t8aDbM1GrRokWVBGHOnDmUlpYCod/pGjFiBBUVFezfv7/K7ygVFxfTokULAJYvX87zzz8PwAUXXEDbtm0BOO2001i9ejW7du2iefPm9OzZk9LSUl599VVmzJgBwDPPPMPMmTM5cOAAFRUVrFmzpjLBGjFiBACvv/46a9asoaioCID9+/fTt2/fKufxySefsHPnTgYMGACEenOGDx9e5/kXFRUxbtw4Lr/8ci655BLy8/MpKSmhpKSEHj16ALB7927Wr1/PMcccc1j5upIroLJHL1ykmf2GDh3KqFGjaN68OY8//jijR49myZIlNZaPdr/1pQRLREQy009+kuoaiEiy1dbj9OUv174+Ly+qHqv6uOGGGxg3bhzFxcUsW7aMSZMmVa5r2bJllW0jfbBv1qwZBQUFzJ49mzPPPJPu3buzdOlSNmzYQLdu3di4cSP3338/q1atom3btlx55ZXs3bv3sGO4O4MGDeLpp5+O6/kBTJgwgQsuuICFCxfSp08fFi9ejLtzyy23cN1111XZ9v33349qnytXrqwse9ddd5Gfn8+ysH+b8vJyBkborWzXrl3l62uuuYbx48cD1Fg+Ly+PnTt3cuDAAZo2bUp5eTlf/epXozvxWijBEhGRzHTmmamuQaMSy71f6aix9erUFf90rLPU7ZNPPqFjx44ANc58B6GhgPPnz+f2229n0aJFVSZwOOuss7j//vt58sknOeWUUxg3bhynnXYaZsann35Ky5YtadOm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f6rhmIurlwlcRujerD0R1kWq3yp3H0ZoCOULhHr5IBSfe6rF58vu/vShotHsX0REEk8JlohIlnD3T4CJwKNmdpGZfdnMmpnZEDOL5r6dloQ+yG8BMLP/JtSDFQ/zgKFmNtjMmphZjpkNNLP8ugqa2eVmdoyFHAvcA7zSkEq4uxO6/+t2C01n38LMvgLMItRT93ANRScDZ5rZPWaWa2atzewG4ApgfDTHNrMvBefSxt0/Bz4lNGEHhBLbMWbWOzjPlmZ2gZm1DtZvJjSDooiIpJgSLBGRLOLuDwDjgNsJJUofEOqReiGKsmsIzbD3GqEP9KcQmpo8HvX6gNBU8beG1etmovs7dSLwF2B3UJ93CN2z1NC6/Br4NnAToWGVFcDpwAB3j3SfFe6+ntCQxlMJ3f9VQajHa7C71ydG3wbeN7NPgTGE7k3D3UsJndMjhIYbvgtcGVbup4SSwp3hMw+KiEjyWejLOhEREYnEzM4DngbOcfeyFFdHRETSnBIsERGROpjZUKCju0eaGENERKSSEiwREREREZE40T1YIiIiIiIicaIES0REREREJE7q+rHJpMjLy/OCgoJUV0NERERERCQqq1ev3uru7asvT4sEq6CggNLS0lRXQ0REMsk774SeTzghtfUQEZGMZGb/jLQ8LRIsERGRuLvuutDzsmUprYaIiGQXJVgiIiLS6Fw9Z1Wt65+48vQk1UREpCpNciEiIiIiIhIn6sESERGRjFNbD5d6tzLH559/Tnl5OXv37k11VSSD5eTkkJ+fT7NmzaLaXgmWiIiIiDRK5eXltG7dmoKCAsws1dWRDOTubNu2jfLycjp37hxVGSVYIiKSmW6/PdU1EJEE27t3r5IrSSgzo127dmzZsiXqMkqwREQkM517bqprICJJoORKEq2+15gmuRARkcxUVhZ6iIiIJJESLBERyUw/+EHoISKSQK1ataryfs6cOYwdOzamfRYUFLB169aY9hFP69ato7CwkB49erBhwwZmzJhBt27duPzyy+u1n507d/LYY481qA5z586la9eudO3alblz50bcZs6cObRv357CwkIKCwuZNWtWneU3btxI79696dq1KyNGjGD//v0Nql84DREUERERzbonkiIHDhygadPEfiQ/ePAgTZo0aXD5F154gWHDhjF58mQAHnvsMRYtWhT1pA+HHEqwvvvd79ar3Pbt25k8eTKlpaWYGaeddhrFxcW0bdv2sG1HjBjBI488EnX58ePHc9NNNzFy5EjGjBnDE088wfXXX1+v+lWnHiwRERERkQR48cUX6d27Nz169ODcc89l8+bNAEyaNIlrr72W8847jyuuuIJt27Zx3nnn0aNHD6677jrcHYApU6YwY8YMAG666Sa+/vWvA/DKK6/wrW99C4Drr7+eXr16cdJJJ3HnnXdWHrugoIC77rqLfv368Zvf/IaSkhL69u1Lz549GT58OLt37z6svmVlZfTp04fu3btz8cUXs2PHDhYuXMj06dOZNWsWZ599NmPGjOG9996juLiYBx98kD/96U+VPUY9evRg165dAEydOpXTTz+d7t27V9ZrwoQJbNiwgcLCQm6++eao4/jHP/6RQYMGkZubS9u2bRk0aBAvvfRSzOXdnSVLlnDppZcCMHr0aF544YWo91sT9WCJiIg0ErX1MoF6mkQYOPDwZZddBt/9LuzZA9/4xuHrr7wy9Ni6FYIP2pWWLavzkJ999hmFhYWV77dv305xcTEA/fr14/XXX8fMmDVrFlOmTGHatGkArF69mhUrVtCiRQtuvPFG+vXrx8SJE/nDH/7AzJkzATjrrLOYNm0aN954I6Wlpezbt4/PP/+cFStW0L9/fwDuuececnNzOXjwIOeccw5vvfUW3bt3B0K/37RixQq2bt3KJZdcwuLFi2nZsiX33XcfDzzwABMnTqxyLldccQUPP/wwAwYMYOLEiUyePJnp06czZswYWrVqxQ9/+EMAXnrpJZYuXUpeXh5Dhw7l0UcfpaioiN27d5OTk0NJSQnr16/njTfewN0pLi5m+fLl3Hvvvfz973+nLOz+2MLCwirvI9m0aROdOnWqfJ+fn8+mTZsibvvcc8+xfPlyjj/+eB588EE6depUY/lt27Zx5JFHVvYg1rbf+lCCJSIiIiLSQC1atKiSIMyZM4fS0lIg9DtdI0aMoKKigv3791cZUldcXEyLFi0AWL58Oc8//zwAF1xwQeXQt9NOO43Vq1eza9cumjdvTs+ePSktLeXVV1+t7Nl65plnmDlzJgcOHKCiooI1a9ZUJlgjRowA4PXXX2fNmjUUFRUBsH//fvr27VvlPD755BN27tzJgAEDgFBvzvDhw+s8/6KiIsaNG8fll1/OJZdcQn5+PiUlJZSUlNCjRw8Adu/ezfr16znmmGMOK19XcgVU9uiFizSz39ChQxk1ahTNmzfn8ccfZ/To0SxZsqTG8tHut76UYImISGb6yU9SXQNB93aFUyySoLYepy9/ufb1eXlR9VjVxw033MC4ceMoLi5m2bJlTJo0qXJdy5Ytq2wb6YN9s2bNKCgoYPbs2Zx55pl0796dpUuXsmHDBrp168bGjRu5//77WbVqFW3btuXKK69k7969hx3D3Rk0aBBPP/10XM8PQsP+LrjgAhYuXEifPn1YvHgx7s4tt9zCddddV2Xb999/P6p9rly5srLsXXfdRX5+PsvC/m3Ky8sZGKG3sl27dpWvr7nmGsaPHw9QY/m8vDx27txZeR9ceXk5X/3qV6M78VroHiwREclMZ54ZeoiIpMgnn3xCx44dAWqc+Q5CQwHnz58PwKJFi9ixY0eVdffffz9nnXUW/fv35/HHH6ewsBAz49NPP6Vly5a0adOGzZs3s2jRooj779OnD3/+85959913AdizZw//+Mc/qmzTpk0b2rZty6uvvgrAU089VdmbVZsNGzZwyimnMH78eHr16sW6desYPHgwTz75ZOV9Xps2beLjjz+mdevWlfdo1aZ3796UlZVRVlZGcXExgwcPpqSkhB07drBjxw5KSkoYPHjwYeUqKioqXy9YsIBu3boB1FjezDj77LN59tlngdC/0bBhw+qsX13UgyUiIpnpL38JPSvJAuq+f0tipxhLdZMmTWL48OF07NiRPn36sHHjxojb3XnnnYwaNYqePXsyYMCAKkPp+vfvzz333EPfvn1p2bIlOTk5lfdfnXrqqfTo0YOTTjqJ4447rnIIYHXt27dnzpw5jBo1in379gFw9913c/zxx1fZbu7cuYwZM4Y9e/Zw3HHHMXv27DrPcfr06SxdupQmTZpw4oknMmTIEJo3b87atWsrhyG2atWKefPm0aVLF4qKijj55JMZMmQIU6dOjeoerNzcXO644w5OPz3U0ztx4kRyc3MrX/fq1Yvi4mJmzJjBggULaNq0Kbm5ucyZM6fO8vfddx8jR47k9ttvp0ePHlx99dV1nnNdLNLYw2Tr1auXHxqrKiIiEheHho/EechPKsUyyUUsH/5jGb6WqGFxqTqf2qRjnTLd2rVrK3spRBIp0rVmZqvdvVf1bdWDJSIiEmepmu1PPSgiIqmne7BERERERETipME9WGbWCfgF8BXgC2Cmuz9kZrnAr4EC4H3gMnffUdN+RERE6qLZ11Ir035/S0P5Mou7x2VqbZGa1PeWqlh6sA4A/8/duwF9gO+Z2YnABOAVd+8KvBK8FxERERGJq5ycHLZt21bvD8Ai0XJ3tm3bRk5OTtRlGtyD5e4VQEXwepeZrQU6AsOAgcFmc4FlwPiGHkdERKRBpk9PdQ0kRrqnTOqSn59PeXk5W7ZsSXVVJIPl5OSQn58f9fZxmeTCzAqAHsBK4Ogg+cLdK8zsqBrKXAtcC0T8VWcREZGYFBamugYikmDNmjWjc+fOqa6GSBUxT3JhZq2A54AfuPun0ZZz95nu3svde7Vv3z7WaoiIiFS1eHHoISIikkQx9WCZWTNCydV8d38+WLzZzDoEvVcdgI9jraSIiEi93X136Pncc1Nbjwg09C1EcRCRTNTgHiwLTdfyBLDW3R8IW7UAGB28Hg38ruHVExERERERaTxi6cEqAr4N/M3MyoJltwL3As+Y2dXAv4DhMdVQRERE0pp6otJXpk2xL9IYxDKL4Aqgph8dOKeh+xUREREREWms4jKLoIiIiEg2SFRvXSw9TepBFEkvSrBERCQz/c//pLoGIiKShZRgiYhIyiXkG/gTToj/PsOo10BERCKJ+XewRERE0tKLL4YeIiIiSaQeLBGRLJNps4rVdD433zuJ//xKaxg6tN5lofHFQTJbNvWY6v+lNHbqwRIREREREYkT9WCJiCRQNn0Tmy09YyJSt0xrD0TqQz1YIiIiIiIicaIeLBGRDKTel5B1H+1iqmIh0iCJ7IVSGyWZTAmWiIhkpFnXTE51FUREJAspwRIRSZFYvsHV/Qt129Hu6FRXQSTtxdIOpaIXSvd2SWOge7BERCQjnb7yZU5f+XKqqyEiIllGPVgiIpIUyf62e+DS5wBY1XtQUo8rIhIum2aTlRD1YImIiIiIiMSJerBEREREJOPp/i1JFvVgiYiIiIiIxIl6sEREGqFE3s+k36cRkcYqUe2X7qOS+lCCJSIiGeln37s31VUQEZEspARLRBok077Ny7TzEdjd+shUV0FEGhH13ku86B4sERHJSEUrfk/Rit+nuhoiIpJllGCJiEhGOnPF7zlTCZaIiCSZEiwREREREZE40T1YIpJ0mXa/k8bti4hIQ8Ty96Ouv5eZ9re2MVEPloiIiIiISJyoB0tEsoJ6mURERBKrrr+12dJzpgRLREQy0kM3TU91FUREJAspwRJp5GL5tqixjc/WN2NSH/ub56S6CiKSBVI1QiKW42pUR2IpwRJJA4lMHBpbI6o/GBIvZy95FoClX780xTUREZFsokkuREQkI/V6YzG93lic6mqIiEiWUQ+WSCOQip4Z9Qb9m2IhIiKSWI3ttoXaJKwHy8zON7N3zOxdM5uQqOOIiIiIiIiki4T0YJlZE+BRYBBQDqwyswXuviYRx5P0Fcu3Ean6JkO9FbFTDEVERKS6bPl8kKgerDOAd939PXffD/wKGJagY4mIiIiIiKQFc/f479TsUuB8d/9O8P7bQG93Hxu2zbXAtcHbE4B34l6R2OQBW1NdiSyjmCefYp58inlyKd7Jp5gnn2KefIp5cqVrvI919/bVFyZqkguLsKxKJufuM4GZCTp+zMys1N17pboe2UQxTz7FPPkU8+RSvJNPMU8+xTz5FPPkamzxTtQQwXKgU9j7fODDBB1LREREREQkLSQqwVoFdDWzzmb2JWAksCBBxxIREREREUkLCRki6O4HzGws8EegCfCku7+diGMlUNoOX8xginnyKebJp5gnl+KdfIp58inmyaeYJ1ejindCJrkQERERERHJRgn7oWEREREREZFsowRLREREREQkTrIuwTKzXDN72czWB89ta9juSDN71szWmdlaM+tbV3kzu8XM3jWzd8xscLLOKd3VI+bvm9nfzKzMzErDlv86WFYWbFMWLC8ws8/C1j2epFNKa3GI9yQz2xQW12+ErdM1HkEcYj41aGveMrPfmtmRwXJd4zWIQ8zVltdTtDEPtm1iZn81s9+HLVNbXk9xiLna83qIQ7zVltdTHGKelm151iVYwATgFXfvCrwSvI/kIeAld/9P4FRgbW3lzexEQrMlngScDzxmZk0SdhaNS7QxBzjb3QvDf+vA3UcEywqB54Dnw7bfcGidu49JROUboZjiHXgwLK4LQdd4HWKN+cvAye7eHfgHcEvYOl3jkcUac7Xl9VefmH+ff//dBNSWN1BMMQ+oPY9erPFWW15/scY8LdvybEywhgFzg9dzgYuqb2BmRwBnAU8AuPt+d99ZR/lhwK/cfZ+7bwTeBc6If/UbpTpjHg0zM+Ay4On4VCtjxSXeNexX13hkMcXc3Uvc/UDw9nVCvx0otYv1OldbXn9RxdzM8oELgFk1rFdbHr24xLyG/eo6P1xM8VZb3iCxXuNp2ZZnY4J1tLtXAATPR0XY5jhgCzA76IqcZWYt6yjfEfggbB/lwTKJLuYADpSY2WozuzbC+v7AZndfH7asc/Bv9Ccz6x/fajda8Yj32GCIw5Nh3e26xmsWr2sc4CpgUdh7XeORxRpzteX1F23MpwM/Ar6oYb3a8ujFI+Zqz6MXr2sc1JZHK9aYp2VbnpDfwUo1M1sMfCXCqtui3EVToCdwg7uvNLOHCHU53lHbYSMsy5o58OMQc4Aid//QzI4CXjazde6+PGz9KKp+41kBHOPu28zsNOAFMzvJ3T+t9wk0MgmO98+AHxO6fn8MTCP0h0LXeIKvcTO7DTgAzA8WZe01DklrVw47bIRlus6jjLmZXQh87O6rzWxgDZupLQ+T4JirPa8mGde42vKqktSuHFYswrKkXeMZmWC5+7k1rTOzzWbWwd0rzKwD8HGEzcqBcndfGbx/ln+PCa2pfDnQKWwf+cCHMZ1IIxKHmOPuHwbPH5vZbwl15S4P9tEUuAQ4LWz7fcC+4PVqM9sAHA+UkuESGW933xy2r58Dh24m1TVegzhd46OBC4Fz3EM/UJjN1zgkPOZqyyOIQ8yLgGILTaaQAxxhZvPc/VvBPtSWV5PImKs9P1wSrnG15dUkOOZp2ZZn4xDBBcDo4PVo4HfVN3D3j4APzOyEYNE5wJo6yi8ARppZczPrDHQF3oh/9RulOmNuZi3NrPWh18B5wN/DNjkXWOfu5WFl2ltww6KZHUco5u8l5Awal5jiHTRQh1zMv/8ddI3XLNaYnw+MB4rdfU9YGV3jNYu1XVFbXn/R/P28xd3z3b2A0A3mSw598AyoLa+fmGKu9rzeYo232vL6i7VdSc+23N2z6gG0IzTLyPrgOTdY/lVgYdh2hYS+WXgLeAFoW1v5YN1twAbgHWBIqs81XR7RxJzQfW9vBo+3gduq7WMOMKbasm8G274J/C8wNNXnmg6PWOMNPAX8Lbj2FwAdwtbpGk9MzN8lNFa8LHg8HizXNZ64mKstT0DMq20/EPh9tWVqy5MYc7XnSY+32vLkxzwt23ILKiAiIiIiIiIxysYhgiIiIiIiIgmhBEtERERERCROlGCJiIiIiIjEiRIsERERERGROFGCJSIiIiIiEidKsEREREREROJECZaIiIiIiEicKMESERERERGJEyVYIiIiIiIicaIES0REREREJE6UYImIiIiIiMSJEiwREREREZE4UYIlIiIRmdkkM5uX6npUZ2bLzOw7qa5HtMysyMzWm9luM7vIzI42s+VmtsvMpqW6fiIiEl9KsEREspiZ/ZeZlQYf/ivMbJGZ9Ut1veLBzJaYmZtZ0xj2UWsyZ2b5ZjbfzLaZ2f+Z2RtmdmG1ze4CHnH3Vu7+AnAtsBU4wt3/X6LqJiIiqaEES0QkS5nZOGA68BPgaOAY4DFgWAqrFRdmdjnQ4MQqymPkAiuA/cBJQB7wIPBLM7s0bNNjgbervV/j7p7I+omISGoowRIRyUJm1oZQz8r33P15d/8/d//c3V9095vDNv2Smf0iGM72tpn1CtvHBDPbEKxbY2YXh6270sxWmNn9ZrbDzDaa2ZCw9cvM7Mdm9uegfImZ5YWt72NmfzGznWb2ppkNrOe53Qn8qEHBid5NwG7ganf/yN0/c/engXuAaRayATgOeDHoJXwaGA38KHh/rpmdEfQifmpmm83sgbBziRgHM7sH6A88EuznkQSfq4iIREkJlohIduoL5AC/rWO7YuBXwJHAAiD8g/wGQh/y2wCTgXlm1iFsfW/gHUI9O1OAJ8zMwtb/F/DfwFHAl4AfAphZR+APwN1AbrD8OTNrH+W5/QT4GfBRlNs31CDgOXf/otryZwj1Bh7v7l2AfwFDgyGCo4D5wJTg/WLgIeAhdz8C6BKUrzUO7n4b8CowNtjP2ASfq4iIREkJlohIdmoHbHX3A3Vst8LdF7r7QeAp4NRDK9z9N+7+obt/4e6/BtYDZ4SV/ae7/zwoOxfoQGgo4iGz3f0f7v4ZoaSiMFj+LWBhcNwv3P1loBT4Rl0nFfSwFQEP17VtHOQBFRGWV4Stj8bnwNfMLM/dd7v768HyBsdBRERSRwmWiEh22gbkRTEBRHgv0B4g51AZM7vCzMqC4Ws7gZOpmlRUlnX3PcHLVrXs+9C6Y4Hhh/Yb7LsfoQStRmb2H4TuIft+FIkjZnZrMLxut5k9Xtf2EWytoU4dwtZH42rgeGCdma0KmySjQXEQEZHUSugNwCIikrZeA/YCFwHP1rewmR0L/Bw4B3jN3Q+aWRlgtRaMzgfAU+5+TT3LHQH0An4djERsEiwvN7Ph7v5q+Mbu/hNCwwkbajHwTTObXG2Y4GWEzuEf0ezE3dcDo4IE8RLgWTNrR91x0CQZIiJpSD1YIiJZyN0/ASYCjwa/zfRlM2tmZkPMbEoUu2hJ6AP+FgAz+29CPVjxMA8YamaDzayJmeWY2UAzy6+j3CfAVwkNNSzk30PpTgNWxqlu4R4klNQ9YWZfCeo5CrgNuDnaWQLN7FvBfVVfADuDxQepOw6bCU2gISIiaUQJlohIlnL3B4BxwO2EEqUPgLHAC1GUXQNMI9QTthk4BfhznOr1AaGp4m8Nq9fN1PE3y0M+OvQIygJsdvf98ahbteNtIzRkLwdYQ2jY5Tjg28E9adE6H3jbzHYTmvBipLvvjSIODwGXBrM0zojHOYmISOxMP8MhIiIiIiISH+rBEhERERERiRMlWCIiIiIiInGiBEtERERERCROlGCJiIiIiIjESVr8DlZeXp4XFBSkuhoiIiIiIiJRWb169VZ3b199eVokWAUFBZSWlqa6GiIikkneeSf0fMIJqa2HiIhkJDP7Z6TlaZFgiYiIxN1114Wely1LaTVERCS7KMESERERCVw9Z1Wt65+48vQk1UREGitNciEiIiIiIhIn6sESERGJs0zrBcm084lFbbHIpjiki88//5zy8nL27t2b6qpIBsvJySE/P59mzZpFtb0SLBERERFplMrLy2ndujUFBQWYWaqrIxnI3dm2bRvl5eV07tw5qjJKsEREJDPdfnudm6g3QqRx27t3r5IrSSgzo127dmzZsiXqMkqwREQkM517bqprICJJoORKEq2+15gmuRARkcxUVhZ6iIiIJJESLBERyUw/+EHoISKSQK1ataryfs6cOYwdOzamfRYUFLB169aY9hFP69ato7CwkB49erBhwwZmzJhBt27duPzyy+u1n507d/LYY481qA5z586la9eudO3alblz50bcZs6cObRv357CwkIKCwuZNWtWneU3btxI79696dq1KyNGjGD//v0Nql84JVgiIiIiIily4MCBhB/j4MGDMZV/4YUXGDZsGH/961/p0qULjz32GAsXLmT+/Pn12k9DE6zt27czefJkVq5cyRtvvMHkyZPZsWNHxG1HjBhBWVkZZWVlfOc736mz/Pjx47nppptYv349bdu25Yknnqh3/arTPVgiIiJppK4p0WujiTlE0suLL77I3Xffzf79+2nXrh3z58/n6KOPZtKkSXz44Ye8//775OXl8fDDDzNq1Ci2bNnCGWecgbsDMGXKFHJycrjxxhu56aabePPNN1myZAmvvPIKs2fPZt68eVx//fWsWrWKzz77jEsvvZTJkycDoV6wq666ipKSEsaOHUtubi533nkn+/bto0uXLsyePfuw3reysjLGjBnDnj176NKlC08++SSvvfYa06dPp0mTJixfvpwTTjiB9957j+LiYq666ip69uzJ97//fSB0r9Ly5ctp3bo1U6dO5ZlnnmHfvn1cfPHFTJ48mQkTJrBhwwYKCwsZNGgQU6dOjSqOf/zjHxk0aBC5ubkADBo0iJdeeolRo0bFVH7kyJEsWbKEX/7ylwCMHj2aSZMmcf3110e135oowRIRERGRzDBw4OHLLrsMvvtd2LMHvvGNw9dfeWXosXUrXHpp1XXLltV5yM8++4zCwsLK99u3b6e4uBiAfv368frrr2NmzJo1iylTpjBt2jQAVq9ezYoVK2jRogU33ngj/fr1Y+LEifzhD39g5syZAJx11llMmzaNG2+8kdLSUvbt28fnn3/OihUr6N+/PwD33HMPubm5HDx4kHPOOYe33nqL7t27A6Hfb1qxYgVbt27lkksuYfHixbRs2ZL77ruPBx54gIkTJ1Y5lyuuuIKHH36YAQMGMHHiRCZPnsz06dMZM2YMrVq14oc//CEAL730EkuXLiUvL4+hQ4fy6KOPUlRUxO7du8nJyaGkpIT169fzxhtv4O4UFxezfPly7r33Xv7+979TFnZ/bGFhYZX3kWzatIlOnTpVvs/Pz2fTpk0Rt33uuedYvnw5xx9/PA8++CCdOnWqsfy2bds48sgjadq0aZ37rQ8lWCIiIhKThva6qcctPvRzA6nVokWLKgnCnDlzKC0tBUK/0zVixAgqKirYv39/ld9RKi4upkWLFgAsX76c559/HoALLriAtm3bAnDaaaexevVqdu3aRfPmzenZsyelpaW8+uqrzJgxA4BnnnmGmTNncuDAASoqKlizZk1lgjVixAgAXn/9ddasWUNRUREA+/fvp2/fvlXO45NPPmHnzp0MGDAACPXmDB8+vM7zLyoqYty4cVx++eVccskl5OfnU1JSQklJCT169ABg9+7drF+/nmOOOeaw8nUlV0Blj164SDP7DR06lFGjRtG8eXMef/xxRo8ezZIlS2osH+1+60sJloiIZKaf/CTVNRCRZKutx+nLX659fV5eVD1W9XHDDTcwbtw4iouLWbZsGZMmTapc17JlyyrbRvpg36xZMwoKCpg9ezZnnnkm3bt3Z+nSpWzYsIFu3bqxceNG7r//flatWkXbtm258sor2bt372HHcHcGDRrE008/HdfzA5gwYQIXXHABCxcupE+fPixevBh355ZbbuG6666rsu37778f1T5XrlxZWfauu+4iPz+fZWH/NuXl5QyM0FvZrl27ytfXXHMN48ePB6ixfF5eHjt37uTAgQM0bdqU8vJyvvrVr0Z34rVQgiUiIpnpzDNTXYNGJZZ7v9JRY+vVqSv+6Vhnqdsnn3xCx44dAWqc+Q5CQwHnz5/P7bffzqJFi6pM4HDWWWdx//338+STT3LKKacwbtw4TjvtNMyMTz/9lJYtW9KmTRs2b97MokWLIiYeffr04Xvf+x7vvvsuX/va19izZw/l5eUcf/zxldu0adOGtm3b8uqrr9K/f3+eeuqpyt6s2mzYsIFTTjmFU045hddee41169YxePBg7rjjDi6//HJatWrFpk2baNasGa1bt2bXrl117rN3795Vera2b9/OrbfeWhmXkpISfvrTnx5WrqKigg4dOgCwYMECunXrBsDgwYMjljczzj77bJ599llGjhzJ3LlzGTZsWJ31q0uDEywz6wT8AvgK8AUw090fMrNc4NdAAfA+cJm7R57mQ0REJFH+8pfQsxItEUmRSZMmMXz4cDp27EifPn3YuHFjxO3uvPNORo0aRc+ePRkwYECVoXT9+/fnnnvuoW/fvrRs2ZKcnJzK+69OPfVUevTowUknncRxxx1XOQSwuvbt2zNnzhxGjRrFvn37ALj77rurJFgQSgIPTXJx3HHHMXv27DrPcfr06SxdupQmTZpw4oknMmTIEJo3b87atWsrhyG2atWKefPm0aVLF4qKijj55JMZMmQIU6dOjeoerNzcXO644w5OPz30RcPEiRMrJ6yYOHEivXr1ori4mBkzZrBgwQKaNm1Kbm4uc+bMqbP8fffdx8iRI7n99tvp0aMHV199dZ3nXBeLNPYwqoJmHYAO7v6/ZtYaWA1cBFwJbHf3e81sAtDW3cfXtq9evXr5obGqIiIicXHoW9xahvwkqpcjlt6IVM0imIoerET2yjT03zZd49/QOmd6z9fatWsreylEEinStWZmq929V/VtG/w7WO5e4e7/G7zeBawFOgLDgEN9oHMJ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t0ziW99sB8OGNbguNL84SHrLpB5T/b+U5k49WCIiIiIiInGiHiwRkQTKpG9iM6VnTETql27XA5GGUA+WiIiIiIhInKgHS0QkDan3JWTVJ1u4XbEQaZRE9kLpGiXpTAmWiIikpek/npzqJoiISAZSgiUikiKxfIOr+xfqt6nTQalugkiTF8t1KBW9ULq3S5oD3YMlIiJpqffrL9D79RdS3QwREckw6sESEZGkSPa33YPmPwXA0j5DkrpfEZFwmTSbrISoB0tERERERCRO1IMlIiIiImlP929JsqgHS0REREREJE7UgyUi0gwl8n4m/T6NiDRXibp+6T4qaQglWCIikpb+76e3pLoJIiKSgZRgiUijpNu3eel2PAJb23VIdRNEpBlR773Ei+7BEhGRtNR/8XP0X/xcqpshIiIZRgmWiIikpZMXP8fJSrBERCTJNERQRJIu3YbjaViJiIg0Rix/P+r7e5luf2ubE/VgiYiIiIiIxIl6sEQkI6iXSUREJLH0Y84h6sESERERERGJE/VgiTRzsXxb1NzGZ+ubMWmIe8ZPSXUTRCQDpGqERCz71aiOxFKCJSIiaWlnq6xUN0FERDKQEiyRJiCRPTPN7VsqfSMn8XLaS08CMP/bF6S4JSIikkl0D5aIiKSlwiXzKFwyL9XNEBGRDKMeLJFmIBU9M+oN+ppiISIikljN7b7wuiSsB8vMzjSz98xsjZlNSNR+REREREREmoqE9GCZWQvgPmAIUA4sNbPZ7r4iEfuTpiuWbyNS9U2GeitipxiKiIhITZny+SBRPVgnAWvc/QN33wn8GRieoH2JiIiIiIg0Cebu8d+o2QXAme7+o+D9D4A+7j4urMxlwGXB22OA9+LekNjkABtT3YgMo5gnn2KefIp5cineyaeYJ59innyKeXI11Xgf7u6day5M1CQXFmHZXpmcu08DpiVo/zEzsxJ3L0x1OzKJYp58innyKebJpXgnn2KefIp58inmydXc4p2oIYLlwKFh73OBjxO0LxERERERkSYhUQnWUqCbmXU1s/2BUcDsBO1LRERERESkSUjIEEF3321m44B/AC2Ah9z93UTsK4Ga7PDFNKaYJ59innyKeXIp3smnmCefYp58inlyNat4J2SSCxERERERkUyUsB8aFhERERERyTRKsEREREREROIk4xIsM8s2sxfMbHXw3LGWch3M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+OADioqKuPvuu3n55Zere4wKCgrYsmULALfffju9e/emZ8+e1e2aMGECZWVl5Ofnc/XVV0cdx3/84x8MGTKE7OxsOnbsyJAhQ3j++edjru/uvPTSS1xwwQUAjBkzhlmzZkW93dqoB0tERKSZqKuXCdTTJJIKX375Jfn5+dXvP/vsM4qKigAYMGAAr732GmbG9OnTue2227jzzjsBWLZsGYsXL6Z169ZceeWVDBgwgIkTJ/L3v/+dadOmAXDKKadw5513cuWVV1JSUsKOHTvYtWsXixcvZuDAgQDcfPPNZGdns2fPHk4//XSWL19Oz549gdDvNy1evJiNGzdy/vnnM2/ePNq0acOtt97KXXfdxcSJE/c6losvvpjf/e53nHrqqUycOJHJkyczZcoUxo4dS9u2bfnlL38JwPPPP8/8+fPJyclh2LBh3HffffTv35+tW7eSlZVFcXExq1evZsmSJbg7RUVFLFy4kFtuuYV33nmH0rD7Y/Pz8/d6H8m6des49NBDq9/n5uaybt26iGWfeuopFi5cyNFHH83dd9/NoYceWmv9yspKOnToUN2DWNd2G0IJloiIiCSMhh5+TbFIggULal93wAF1r8/JqXt9LVq3br1XgjBjxgxKSkqA0O90jRw5koqKCnbu3LnXkLqioiJat24NwMKFC3n66acBOOecc6qHvp144oksW7aMLVu20KpVK3r16kVJSQmLFi2q7tl64oknmDZtGrt376aiooIVK1ZUJ1gjR44E4LXXXmPFihX0798fgJ07d9KvX7+9juPzzz9n8+bNnHrqqUCoN2fEiBH1Hn///v256qqruPDCCzn//PPJzc2luLiY4uJiCgoKANi6dSurV6/msMMO26d+fckVUN2jFy7SzH7Dhg1j9OjRtGrVigceeIAxY8bw0ksv1Vo/2u02lIYIiohIevrtb0MPEZEU+dnPfsa4ceN4++23+f3vf8/27dur17Vp02avspE+2Lds2ZK8vDwefvhhTj75ZAYOHMj8+fMpKyuje/furF27ljvuuIMXX3yR5cuXc84550Tch7szZMgQSktLKS0tZcWKFTz44INxOcYJEyYwffp0vvzyS/r27cuqVatwd6699trq/a1Zs4ZLL7006m2+/vrr1cMOZ8+eTW5uLh999FH1+vLycg4++OB96nXq1IlWrVoB8OMf/5hly5YB1Fo/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dNjR9RcSkbTSsmVLunbtmupmSIbTEEEREUlL3d9dQvd3l6S6GSIikmHUgyUiImnp3GcfAmBlj5NS3BIREckk6sESERERERGJEyVYIiIiIiIicaIES0REREREJE50D5aIiCTFpTOWproJSVPfsT54Se8ktURERJJNCZaIiKSlP465NtVNEBGRDKQES0RE0tL6LoenugkiIpKBdA+WiIikpRNKF3FC6aJUN0NERDJMTD1YZvYhsAXYA+x290Izywb+AuQBHwLfc/dNsTVTRESkYc54/jEA3sofmOKWiIhIJonHEMHT3H1j2PsJwIvufouZTQjeXxOH/YiISBOWSZNYQOYdr4iIRCcRQwSHAzOD1zOB7yRgHyIiIiIiIk1OrAmWA8VmtszMLguWHeTuFQDB84GRKprZZWZWYmYlGzZsiLEZIiIiIiIiqRfrEMH+7v6xmR0IvGBmq6Kt6O7TgGkAhYWFHmM7REREREREUi6mBMvdPw6ePzWzvwEnAevNrIu7V5hZF+DTOLRTRESkQab/eHKqmyAiIhmo0UMEzayNmbWreg2cAbwDzAbGBMXGAM/E2kgREZGG2tTpIDZ1OijVzRARkQwTSw/WQcDfzKxqO39y9+fNbCnwhJldCvwbGBF7M0VERBqm9+svALC0z5AUt0RERDJJoxMsd/8AOCHC8krg9FgaJSIiEqtB858ClGCJiEhyJWKadhERERERkYwUjx8aFhGRDKEf1xUREamberBERERERETiRAmWiIiIiIhInGiIoIiIpKX/++ktqW5CrRo71PLBS3rHuSUiIhJvSrBERGQv6XKf1dZ2HVLdBBERyUAaIigiImmp/+Ln6L/4uVQ3Q0REMox6sEREJC2dHCRXrww4N8UtiZ/6ehc1hFBEJPXUgyUiIiIiIhInSrBERERERETiRAmWiIiIiIhInCjBEhERERERiRNNciEikmHSZRr2+twzfkqqmyAiIhlICZaIiKSlna2yUt0EERHJQEqwREQkLZ320pMAzP/2BSluSfLU1TupKdxFRJJDCZaISBrKlGGAdSlcMg/IrARLRERST5NciIiIiIiIxEnCerDM7EzgHqAFMN3db0nUvkRERKRusfRqanihiEj0EpJgmVkL4D5gCFAOLDWz2e6+IhH7ExFpjjSMTzKB7gsTkUyTqB6sk4A17v4BgJn9GRgOKMESkbSj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zwcGyw8BPgorVx4sExERSapD//0+lJamuhkikmHatm271/sZM2Ywbty4mLaZl5fHxo0bY9pGPK1atYr8/HwKCgooKytj6tSpdO/enQsvvLBB29m8eTP3339/VGXXrl1Lnz596NatGyNHjmTnzp0Ry82cOZNu3brRrVs3Zs6cWW99d+fKK6/kqKOOomfPnrzxxhsNOoZI4j2LYKT0ziMWNLvMzErMrGTDhg1xboaIiGS6UX+6C37xi1Q3Q0SkQXbv3p3wfezZsyem+rNmzWL48OG8+eabHHnkkdx///3MmTOHxx57rEHbaUiCdc011zB+/HhWr15Nx44defDBB/cp89lnnzF58mRef/11lixZwuTJk9m0aVOd9efOncvq1atZvXo106ZN44orrmjQMUTS2ARrvZl1AQiePw2WlwOHhpXLBT6OtAF3n+buhe5e2Llz50Y2Q0RERESkeXj22Wfp06cPBQUFDB48mPXr1wMwadIkLrvsMs444wwuvvhiKisrOeOMMygoKODyyy/HPdRfcdtttzF16lQAxo8fz7e//W0AXnzxRS666CIArrjiCgoLC+nRowc33nhj9b7z8vL49a9/zYABA/jrX/9KcXEx/fr1o1evXowYMYKtW7fu097S0lL69u1Lz549Oe+889i0aRNz5sxhypQpTJ8+ndNOO42xY8fywQcfUFRUxN13383LL79Mfn5+dQ/Xli1bALj99tvp3bs3PXv2rG7XhAkTKCsrIz8/n6uvvrrWuLk7L730EhdccAEAY8aMYdasWfuU+8c//sGQIUPIzs6mY8eODBkyhOeff77O+s888wwXX3wxZkbfvn3ZvHkzFRUV0f2D1qKx07TPBsYAtwTPz4Qt/5OZ3QUcDHQDlsTUQhERkUZa9ckWbq/lh4gBHrykdxJbIyJJN2jQvsu+9z34yU9g2zY4++x9119ySeixcSMEH8irLVhQ7y6//PJL8vPzq99/9tlnFBUVATBgwABee+01zIzp06dz2223ceeddwKwbNkyFi9eTOvWrbnyyisZMGAAEydO5O9//zvTpk0D4JRTTuHOO+/kyiuvpKSkhB07drBr1y4WL17MwIEDAbj55pvJzs5mz549nH766SxfvpyePXsCoenGFy9ezMaNGzn//POZN28ebdq04dZbb+Wuu+5i4sSJex3LxRdfzO9+9ztOPfVUJk6cyOTJk5kyZQpjx46lbdu2/PKXvwTg+eefZ/78+eTk5DBs2DDuu+8++vfvz9atW8nKyqK4uJjVq1ezZMkS3J2ioiIWLlzILbfcwjvvvENp2HDu/Pz8vd4DVFZW0qFDB/bbL5S65Obmsm7dun1iv27dOg499Ou+nqpyddWvrU6XLl3q/beuTTTTtD8ODAJyzKwcuJFQYvWEmV0K/BsYAeDu75rZE8AKYDfwU3ePrQ9SRERERKSZaN269V4JwowZMygpKQFC08iPHDmSiooKdu7cude030VFRbRu3RqAhQsX8vTTTwNwzjnn0LFjRwBOPPFEli1bxpYtW2jVqhW9evWipKSERYsWVfdsPfHEE0ybNo3du3dTUVHBihUrqhOskSNHAvDaa6+xYsUK+vfvD8DOnTvp16/fXsfx+eefs3nzZk499VQg1OszYsSIeo+/f//+XHXVVVx44YWcf/755ObmUlxcTHFxMQUFBQBs3bqV1atXc9hhh+1Tv2ZyBVT34IWLNPFEbeXqqh/tthui3gTL3UfXsur0WsrfDNwcS6NERERERGJWV4/TAQfUvT4nJ6oeq4b42c9+xlVXXUVRURELFixg0qRJ1evatGmzV9lIH/JbtmxJXl4eDz/8MCeffDI9e/Zk/vz5lJWV0b17d9auXcsdd9zB0qVL6dixI5dccsle04tX7cPdGTJkCI8//nhcjw9Cw/7OOecc5syZQ9++fZk3bx7uzrXXXsvll1++V9kPP/wwqm3m5OSwefNmdu/ezX777Ud5eTkHH3zwPuVyc3NZEPZvVl5ezqBBg+qsn5uby0cffbRXnUjbboh4T3IhIiLSJDz93Z/w9Hd/0uj6l85YWudDRKShPv/8cw45JDTBdvgMdzWdcsop1RNGzJ07t3qihqp1d9xxB6eccgoDBw7kgQceID8/HzPjiy++oE2bNrRv357169czd+7ciNvv27cvr7zyCmvWrAFg27ZtvP/++3uVad++PR07dmTRokUAPPLII9W9WXUpKyvj+OOP55prrqGwsJBVq1YxdOhQHnrooer7vNatW8enn35Ku3btqu/RqouZcdppp/Hkk08CodgNHz58n3JDhw6luLiYTZs2sWnTJoqLixk6dGid9YuKivjjH/+Iu/Paa6/Rvn37mIYHghIsERFJU2XdelLWrWeqmyEiUm3SpEmMGDGCgQMHkpOTU2u5G2+8kYULF9KrVy+Ki4v3Gko3cOBAKioq6NevHwcddBBZWVnV91+dcMIJFBQU0KNHD374wx9WDwGsqXPnzsyYMYPRo0fTs2dP+vbty6pVq/YpN3PmTK6++mp69uxJaWnpPvdoRTJlyhSOO+44TjjhBFq3bs1ZZ53FGWecwfe//3369evH8ccfzwUXXMCWLVvo1KkT/fv357jjjque5CL8/rVwVfeJHXXUUVRWVnLppZcCUFJSwo9+9CMAsrOzueGGG+jduze9e/dm4sSJZGdn11n/7LPP5ogjjuCoo47ixz/+cdSzGtbFIo07TLbCwkKvGpsqIiKZp74eobomo6it7pGrlwPUmWQ1ZrvR1BWR1Fi5ciXdu3dPdTMkDUU6t8xsmbsX1iyrHiwREUlL5z91P+c/Ffs3kSIiIg2hBEtERERERCROGvs7WCIiIkmTqEklNFmFiIjEm3qwRERERCRtNIX5BSS9NPScUoIlIiIiImkhKyuLyspKJVkSN+5OZWUlWVlZUdfREEEREUlLf/7+ValugogkWW5uLuXl5WzYsCHVTZE0kpWVRW5ubtTllWCJiEha+uiwo1PdBBFJspYtW9K1a9dUN0MynIYIiohIWur+7hK6v7sk1c0QEZEMox4sERFJS+c++xAAK3uclOKWiIhIJlEPloiIiIiISJwowRIREREREYkTDREUEZGk0I/6iohIJlAPloiIiIiISJyoB0tERNLSH8dcm9Dtx9Ij9+AlvePYEhERaUqUYImISFpa3+XwVDdBREQyUEwJlpl9CGwB9gC73b3QzLKBvwB5wIfA99x9U2zNFBERaZgTShcB8Fb+wBS3REREMkk87sE6zd3z3b0weD8BeNHduwEvBu9FRESS6oznH+OM5x9LdTNERCTDJGKSi+HAzOD1TOA7CdiHiIiIiIhIkxPrPVgOFJuZA79392nAQe5eAeDuFWZ2YKSKZnYZcBnAYYcdFmMzREREmo+6JsjQBBgiIs1brAlWf3f/OEiiXjCzVdFWDJKxaQCFhYUeYztERERERERSLqYEy90/Dp4/NbO/AScB682sS9B71QX4NA7tFBGRJk4/JCwiIhJDgmVmbYD/cvctweszgF8Ds4ExwC3B8zPxaKiIiEhDTP/x5FQ3QUREMlAsPVgHAX8zs6rt/MndnzezpcATZnYp8G9gROzNFBERaZhNnQ5KdRNERCQDNTrBcvcPgBMiLK8ETo+lUSIiIrHq/foLACztMyTFLRERkUwS6yQXIiIiTdKg+U8BSrBERCS5lGCJiEjUNJGFiIhI3RLxQ8MiIiIiIiIZSQmWiIiIiIhInCjBEhERERERiRPdgyUiImnp/356S6qbICIiGUgJloiIpKWt7TqkugkiIpKBlGCJiMhe0mWmwP6LnwPglQHnprglIiKSSXQPloiIpKWTFz/HyUGSJSIikizqwRIREWlC6upBfPCS3klsiYiINIZ6sEREREREROJEPVgiIhkmXe6xEhERaYrUgyUiIiIiIhIn6sESEZG0dM/4KalugoiIZCAlWCIikpZ2tspKdRPirr7hnZoEQ0Qk9ZRgiYhIWjrtpScBmP/tC1LckuSJ5f46JWciIvGhBEtEJA1pIgsoXDIPyKwES0REUk+TXIiIiIiIiMRJwnqwzOxM4B6gBTDd3W9J1L5ERNKRfnBWkknnm4hIfCQkwTKzFsB9wBCgHFhqZrPdfUUi9icikmk0BFCSSZNriIhEL1E9WCcBa9z9AwAz+zMwHFCCJSJNUqISlro+eCpJknSRiv8/IiJNlbl7/DdqdgFwprv/KHj/A6CPu48LK3MZcFnw9hjgvbg3JDY5wMZUNyLDKObJp5gnn2KeXIp38inmyaeYJ59inlxNNd6Hu3vnmgsT1YNlEZbtlcm5+zRgWoL2HzMzK3H3wlS3I5Mo5smnmCefYp5cinfyKebJp5gnn2KeXM0t3omaRbAcODTsfS7wcYL2JSIiIiIi0iQkKsFaCnQzs65mtj8wCpidoH2JiIiIiIg0CQkZIujuu81sHPAPQtO0P+Tu7yZiXwnUZIcvpjHFPPkU8+RTzJNL8U4+xTz5FPPkU8yTq1nFOyGTXIiIiIiIiGSiRA0RFBERERERyThKsEREREREROIk4xIsM8s2sxfMbHXw3LGWcg+Z2adm9k609c3sWjNbY2bvmdnQRB9Lc9GAmJ8ZxG6NmU0IW/4XMysNHh+aWWmwPM/Mvgxb90CSDqlJi0O8J5nZurC4nh22Tud4BHGI+e1mtsrMlpvZ38ysQ7Bc53gNtcUwbL2Z2dRg/f9v7+xCparCMPy8aAqZFf2YZoZHsMKu0hKh7EaJlNJ+IOwmwSC8CPJCyBAikC4M6i4KoshC9KY/iQIrIm/S/MmfREuPGYmmYJRBcFL4uthrbHfO7Dn7nL1Hz5x5H1jMmrXWt2fNe16+PWtmnb33S5o9WGzZv183Mly9JU2T9LWkQ5IOSnouF1OYY0xljx+XdCDpuivXbo+3oILPb8/5eK+kc5JWpT77vAUlNL9D0reS+iStLhM7onweEV1VgFeANam+BlhfMO5+YDbwQ5l4YBawDxgP9AC9wJjL/X5HQimjOdnFUHqBGcC4pOWsJuNeBV5M9en9/z4u1fUGXgJWN4mxx9un+QPA2FRfn8sr9nhJDXNjFgOfk92PcR6wo4T+pc4L3VYq6j0FmJ3qE4GfBssxLtU0T33HgRuaHNceb5Pm/Y7zG9mNZ+3z6ppPAu4BXs7r2Cm5vOt+wQKWAhtSfQPwSLNBEbEN+H0I8UuBzRHRFxE/A0eBufVMueMpo/lc4GhEHIuIf4DNKe4ikgQ8AWxq31RHBbXoXXBce7w5lTSPiK0RcSGN205270AzkDK+XQq8FxnbgWslTRkkttR5oQsZtt4RcSoi9gBExF/AIWDqpZx8h1LF462wx4upS/MFQG9E/NL+KXc8g2oeEWciYidwfgixI8bn3bjAuikiTgGkx0k1xU8Ffs2NO4FPJg3KaF5Gv/nA6Yg4kmvrkfS9pG8kza9z0h1MHXo/m7ZBvJP7id0eL6YujwOsIPumtIE9/h9lNCwa0yq26nlhtFJF74tImg7cBezINTfLMaa65gFslbRb0jO5MfZ4MbX4nOyer/2/ALbPm1Pl80RH5PK23AfrciPpS2Byk6617XzZJm1dcw38GjQvo9+T/D95nQJujYizkuYAH0u6MyLOlXzNjqXNer8BrEvP15Fty1wxSMyo51J4XNJa4AKwMTV1rccLKOPBojFd7d9hUkXvrFO6CvgAWJXzbVGOMdU1vzciTkqaBHwh6XDakWOKqcPn44AlwAu5fvu8mCr5uCNy+ahcYEXEwqI+Sacb2xfSz7tnhnj4ovgTwLTcuFuAk0M8dsdSg+Yt9ZM0FngMmJN7zT6gL9V3S+oFbgN2Mcppp94RcTp3rLeATweL6QYugceXAw8BCyJtIO9mjxdQxoNFY8a1iK16XhitVNEbSVeQLa42RsSHjQEtcoypqHlENB7PSPqIbDvVNuzxVlTSPLEI2JP3tn3ekiqfJ1rFjhifd+MWwS3A8lRfDnxSU/wWYJmk8ZJ6gJnAdxXnOlooo/lOYKaknvRN0LIU12AhcDgiTjQaJN0oaUyqzyDT/Fgb5t9pVNK7377yR4HGlTTt8WKqav4g8DywJCL+bgTY4wMYLE+Qnj+ljHnAn2mrSKvYqueF0cqw9U7/M/s2cCgiXssHtMgxpprmEyRNBJA0geziOfn8bY83p0peadB/h4193poymg8nduT4vM4rZnRCAa4HvgKOpMfrUvvNwGe5cZvItuecJ1stP90qPvWtJbuyyY/Aosv9XkdKGYLmi8muNNULrO13jHeBlf3aHgcOkl1BZg/w8OV+ryOhVNUbeB84AOwnS1ZTcn32eHs0P0q2p3xvKm+mdnt8oNYDNARWNvID2faR11P/AeDuEvoX5vVuL8PVG7iPbNvO/pyvF6e+whzjUknzGSlX7Et5wx5vs+ap70rgLHBNv2Pa59U0n0z2+fsc8EeqX10Um9pHjM+VJmSMMcYYY4wxpiLduEXQGGOMMcYYY9qCF1jGGGOMMcYYUxNeYBljjDHGGGNMTXiBZYwxxhhjjDE14QWWMcYYY4wxxtSEF1jGGGOMMcYYUxNeYBljjDHGGGNMTfwL/XtxHWorV2YAAAAASUVORK5CYII=\n", + "text/plain": [ + "
      " + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "class TestProgram(AveragerProgramV2):\n", + " \"\"\"Simple program to measure IQ offsets across multiple readout channels.\"\"\"\n", + " \n", + " def _initialize(self, cfg):\n", + " for ch in cfg['ro_chs']:\n", + " self.declare_readout(ch=ch, length=cfg['ro_len'], freq=100)\n", + "\n", + " def _body(self, cfg):\n", + " self.trigger(ros=cfg['ro_chs'], t=0.0)\n", + "\n", + "config_offsets = {\n", + " 'ro_chs': MUXRO_CH + [STDRO_CH],\n", + " 'ro_len': 100.0, # µs, long readout to average noise\n", + "}\n", + "\n", + "print(\"Measuring IQ offsets...\")\n", + "prog = TestProgram(soccfg, reps=1000, final_delay=0.5, cfg=config_offsets)\n", + "\n", + "# Acquire data (offsets are automatically subtracted)\n", + "iq_list = prog.acquire(soc, rounds=1)\n", + "\n", + "# Get raw data (to see the offsets)\n", + "iq_raw = prog.get_raw()\n", + "\n", + "nch = len(prog.ro_chs)\n", + "fig, axes = plt.subplots(2 * nch, 1, figsize=(12, 3 * nch))\n", + "for i, (ch, rocfg) in enumerate(prog.ro_chs.items()):\n", + " offset = soccfg['readouts'][ch]['iq_offset']\n", + " \n", + " # Check what iq_offset actually looks like\n", + " print(f\"ch {ch} iq_offset: {offset}, type: {type(offset)}\")\n", + " \n", + " # Handle both float and list formats\n", + " if isinstance(offset, (list, tuple, np.ndarray)):\n", + " offset_i, offset_q = offset[0], offset[1]\n", + " else:\n", + " offset_i = offset_q = offset # single value applies to both\n", + " \n", + " bins_i = np.linspace(offset_i - 0.1, offset_i + 0.1, 101)\n", + " bins_q = np.linspace(offset_q - 0.1, offset_q + 0.1, 101)\n", + " nsamp = rocfg['length']\n", + " \n", + " axes[2 * i].hist(iq_raw[i][:, 0, 0] / nsamp, bins=bins_i, alpha=0.7)\n", + " axes[2 * i].axvline(offset_i, color='red', linestyle='--',\n", + " label=f'Hardware offset: {offset_i:.3f}')\n", + " axes[2 * i].set_title(f\"Channel {ch} - I Offset\")\n", + " axes[2 * i].legend()\n", + " \n", + " axes[2 * i + 1].hist(iq_raw[i][:, 0, 1] / nsamp, bins=bins_q, alpha=0.7)\n", + " axes[2 * i + 1].axvline(offset_q, color='red', linestyle='--',\n", + " label=f'Hardware offset: {offset_q:.3f}')\n", + " axes[2 * i + 1].set_title(f\"Channel {ch} - Q Offset\")\n", + " axes[2 * i + 1].legend()\n", + "\n", + "plt.tight_layout()\n", + "print(\"\\nNote: The software automatically subtracts these hardware offsets from acquired data.\")\n", + "print(\"You can manually access raw data via prog.get_raw() if needed.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 8. Performance Benchmarks\n", + "\n", + "Understanding the performance characteristics of different configurations helps optimize your experiments." + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Benchmarking different readout types...\n", + "------------------------------------------------------------\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "07b8ac09ceea4c34a977930d0e331d05", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/1000 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "── Signal diagnosis ──────────────────────────────────────────────────\n", + "⚠️ Magnitude highly variable — trigger may be firing before pulse arrives.\n", + " → Swap pulse/trigger order in _body, or increase trig_time.\n" + ] + } + ], + "source": [ + "class PhaseTrackingProgram(AveragerProgramV2):\n", + " \"\"\"\n", + " Program for tracking shot-to-shot phase stability.\n", + " Useful for qubit stability measurements and noise characterization.\n", + " \"\"\"\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " \n", + " self.declare_gen(ch=gen_ch, nqz=1)\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'], freq=cfg['freq'], gen_ch=gen_ch)\n", + " \n", + " self.add_pulse(ch=gen_ch, name=\"probe\", style=\"const\", \n", + " length=cfg['pulse_len'], freq=cfg['freq'], \n", + " phase=cfg['phase'], gain=cfg['gain'])\n", + " \n", + " def _body(self, cfg):\n", + " self.trigger(ros=[cfg['ro_ch']], t=cfg['trig_time'])\n", + " self.pulse(ch=cfg['gen_ch'], name=\"probe\", t=0)\n", + "\n", + "# Track phase over many shots\n", + "# Phase tracking using get_raw() to recover per-rep IQ data\n", + "n_shots = 500\n", + "config_tracking = {\n", + " 'gen_ch': FSGEN_CH,\n", + " 'ro_ch': STDRO_CH,\n", + " 'freq': 500,\n", + " 'gain': 0.3,\n", + " 'phase': 0,\n", + " 'trig_time': 0.4,\n", + " 'ro_len': 0.5,\n", + " 'pulse_len': 0.3,\n", + "}\n", + "\n", + "print(f\"Tracking phase over {n_shots} shots...\")\n", + "prog_track = PhaseTrackingProgram(soccfg, reps=n_shots, final_delay=0.1, cfg=config_tracking)\n", + "iq_list = prog_track.acquire(soc, rounds=1)\n", + "iq_raw = prog_track.get_raw()\n", + "\n", + "# Extract per-rep IQ points\n", + "# iq_raw shape: (n_ro_channels, n_reps, n_trigs, 2)\n", + "nsamp = prog_track.ro_chs[STDRO_CH]['length']\n", + "iq_shots = iq_raw[0][:, 0, :] # (n_reps, 2)\n", + "i_vals = iq_shots[:, 0] / nsamp\n", + "q_vals = iq_shots[:, 1] / nsamp\n", + "phases_shots = np.angle(i_vals + 1j * q_vals, deg=True)\n", + "\n", + "print(f\"n_shots recovered: {len(phases_shots)}\")\n", + "print(f\"Mean I: {np.mean(i_vals):.4f}\")\n", + "print(f\"Mean Q: {np.mean(q_vals):.4f}\")\n", + "print(f\"Mean magnitude: {np.mean(np.abs(i_vals + 1j*q_vals)):.4f}\")\n", + "print(f\"Std magnitude: {np.std( np.abs(i_vals + 1j*q_vals)):.4f}\")\n", + "print(f\"Phase stability: {np.std(phases_shots):.3f} degrees RMS\")\n", + "\n", + "# ── Diagnostics ────────────────────────────────────────────────────────────────\n", + "fig, axes = plt.subplots(2, 2, figsize=(14, 10))\n", + "\n", + "# 1. IQ cloud\n", + "axes[0, 0].scatter(i_vals, q_vals, alpha=0.3, s=10)\n", + "axes[0, 0].axhline(0, color='k', linewidth=0.5)\n", + "axes[0, 0].axvline(0, color='k', linewidth=0.5)\n", + "axes[0, 0].set_xlabel(\"I\")\n", + "axes[0, 0].set_ylabel(\"Q\")\n", + "axes[0, 0].set_title(\"IQ Cloud (tight cluster = good signal)\")\n", + "axes[0, 0].axis('equal')\n", + "axes[0, 0].grid(True)\n", + "\n", + "# 2. Per-shot magnitude\n", + "magnitudes = np.abs(i_vals + 1j * q_vals)\n", + "axes[0, 1].plot(magnitudes, '.-', alpha=0.5, markersize=3)\n", + "axes[0, 1].set_xlabel(\"Shot\")\n", + "axes[0, 1].set_ylabel(\"Magnitude\")\n", + "axes[0, 1].set_title(\"Per-shot Magnitude (stable & non-zero = signal present)\")\n", + "axes[0, 1].axhline(np.mean(magnitudes), color='red', label=f\"Mean: {np.mean(magnitudes):.4f}\")\n", + "axes[0, 1].legend()\n", + "axes[0, 1].grid(True)\n", + "\n", + "# 3. Phase vs shot\n", + "axes[1, 0].plot(phases_shots, '.-', alpha=0.5, markersize=3)\n", + "axes[1, 0].set_ylabel(\"Phase (degrees)\")\n", + "axes[1, 0].set_xlabel(\"Shot Number\")\n", + "axes[1, 0].set_title(\"Shot-to-Shot Phase Stability\")\n", + "axes[1, 0].axhline(np.mean(phases_shots), color='red',\n", + " label=f\"Mean: {np.mean(phases_shots):.1f}°\")\n", + "axes[1, 0].axhline(np.mean(phases_shots) + np.std(phases_shots), color='orange',\n", + " linestyle='--', label=f\"±1σ: {np.std(phases_shots):.2f}°\")\n", + "axes[1, 0].axhline(np.mean(phases_shots) - np.std(phases_shots), color='orange',\n", + " linestyle='--')\n", + "axes[1, 0].legend()\n", + "axes[1, 0].grid(True)\n", + "\n", + "# 4. Phase histogram\n", + "axes[1, 1].hist(phases_shots, bins=50, alpha=0.7)\n", + "axes[1, 1].set_xlabel(\"Phase (degrees)\")\n", + "axes[1, 1].set_ylabel(\"Counts\")\n", + "axes[1, 1].set_title(f\"Phase Distribution (σ = {np.std(phases_shots):.3f}°)\")\n", + "axes[1, 1].grid(True)\n", + "\n", + "plt.tight_layout()\n", + "plt.show()\n", + "\n", + "# ── Interpretation ─────────────────────────────────────────────────────────────\n", + "mag_mean = np.mean(magnitudes)\n", + "mag_std = np.std(magnitudes)\n", + "phase_std = np.std(phases_shots)\n", + "\n", + "print(\"\\n── Signal diagnosis ──────────────────────────────────────────────────\")\n", + "if mag_mean < 0.01:\n", + " print(\"❌ Magnitude near zero — no signal reaching ADC.\")\n", + " print(\" → Check wiring, increase gain, verify frequency is on resonance.\")\n", + "elif mag_std / mag_mean > 0.5:\n", + " print(\"⚠️ Magnitude highly variable — trigger may be firing before pulse arrives.\")\n", + " print(\" → Swap pulse/trigger order in _body, or increase trig_time.\")\n", + "elif phase_std > 10:\n", + " print(\"⚠️ Large phase scatter despite signal present.\")\n", + " print(\" → Frequency may be off resonance, or DDS phase not reset between reps.\")\n", + " print(\" → Try adding phrst=1 to the pulse, or scan freq to find resonance.\")\n", + "else:\n", + " print(f\"✅ Good signal. Phase stability: {phase_std:.3f}° RMS\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 10. Common Pitfalls and Troubleshooting\n", + "\n", + "This section covers frequently encountered issues and their solutions." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗\n", + "║ COMMON PITFALLS AND SOLUTIONS ║\n", + "╠══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ ║\n", + "║ Issue │ Likely Cause │ Solution ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ No signal in readout │ Wrong physical connection │ Check DAC→ADC loopback cables ║\n", + "║ │ Generator not enabled │ Verify gen_ch is correct ║\n", + "║ │ Wrong nqz setting │ nqz=1 for Nyquist zone 1 ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ Phase rotates with frequency │ Electrical delay not calibrated │ Run calibration sweep (see Section 5) ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ Muxed readout wrong phases │ No frequency matching │ Set gen_ch in declare_readout() ║\n", + "║ │ Tone order mismatch │ Ensure frequencies match order ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ Interpolated gen freq off │ Forgot mixer_freq in tProc v2 │ Use absolute frequencies, not IFs ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ PFB channels swapped │ Tone order mismatch │ Verify pulse_freqs order matches ro_chs ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ Acquisition too slow │ Too many reps without averaging │ Use software averaging or reduce reps ║\n", + "║ │ Long final_delay │ Minimize final_delay when possible ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ Distorted pulse shape │ Pulse too short for ramp │ Ensure flat_len >= ramp_len/2 ║\n", + "║ │ DAC saturation │ Reduce gain ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ Memory errors │ Too many pulses/readouts │ Use loops and dynamic configs ║\n", + "║ │ Pulse/readout length too long │ Limit to < 2^15 samples ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ Fast dynamic readout issues │ Wrong channel type │ Use FASTDYNRO_CH, not DYNRO_CH ║\n", + "║ │ Missing send_readoutconfig │ Send config before each trigger ║\n", + "║ ║\n", + "╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝\n", + "\n" + ] + } + ], + "source": [ + "print(\"\"\"\n", + "╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗\n", + "║ COMMON PITFALLS AND SOLUTIONS ║\n", + "╠══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ ║\n", + "║ Issue │ Likely Cause │ Solution ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ No signal in readout │ Wrong physical connection │ Check DAC→ADC loopback cables ║\n", + "║ │ Generator not enabled │ Verify gen_ch is correct ║\n", + "║ │ Wrong nqz setting │ nqz=1 for Nyquist zone 1 ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ Phase rotates with frequency │ Electrical delay not calibrated │ Run calibration sweep (see Section 5) ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ Muxed readout wrong phases │ No frequency matching │ Set gen_ch in declare_readout() ║\n", + "║ │ Tone order mismatch │ Ensure frequencies match order ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ Interpolated gen freq off │ Forgot mixer_freq in tProc v2 │ Use absolute frequencies, not IFs ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ PFB channels swapped │ Tone order mismatch │ Verify pulse_freqs order matches ro_chs ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ Acquisition too slow │ Too many reps without averaging │ Use software averaging or reduce reps ║\n", + "║ │ Long final_delay │ Minimize final_delay when possible ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ Distorted pulse shape │ Pulse too short for ramp │ Ensure flat_len >= ramp_len/2 ║\n", + "║ │ DAC saturation │ Reduce gain ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ Memory errors │ Too many pulses/readouts │ Use loops and dynamic configs ║\n", + "║ │ Pulse/readout length too long │ Limit to < 2^15 samples ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────────║\n", + "║ Fast dynamic readout issues │ Wrong channel type │ Use FASTDYNRO_CH, not DYNRO_CH ║\n", + "║ │ Missing send_readoutconfig │ Send config before each trigger ║\n", + "║ ║\n", + "╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝\n", + "\"\"\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 11. Summary and Best Practices" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗\n", + "║ BEST PRACTICES SUMMARY ║\n", + "╠══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ ║\n", + "║ ✓ Always calibrate electrical delay before precision phase measurements ║\n", + "║ ✓ Use muxed generators + PFB readout for multi-tone experiments ║\n", + "║ ✓ In tProc v2, specify ABSOLUTE frequencies (not IFs) ║\n", + "║ ✓ Link generators to readouts with gen_ch parameter for automatic frequency matching ║\n", + "║ ✓ Use dynamic readouts for frequency sweeps to save configuration time ║\n", + "║ ✓ Keep pulse lengths within BRAM constraints (< 2^15 samples @ 1ns sample rate = 32.768 µs) ║\n", + "║ ✓ Use software averaging (reps parameter) for noise reduction ║\n", + "║ ✓ Monitor IQ offsets and apply corrections when necessary ║\n", + "║ ✓ Test new configurations with low power and short pulses first ║\n", + "║ ✓ Use progress=True for long acquisitions to monitor status ║\n", + "║ ║\n", + "╠══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ WHEN TO USE EACH TOOL ║\n", + "╠══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ ║\n", + "║ • Full-Speed Generator: Single tone, maximum bandwidth, simple pulses ║\n", + "║ • Interpolated Generator: Fine frequency resolution, shaped pulses ║\n", + "║ • Muxed Generators: Multiple phase-coherent tones ║\n", + "║ • Standard Readout: Fixed-frequency averaging ║\n", + "║ • Dynamic Readout: Frequency sweeps, calibration ║\n", + "║ • Fast Dynamic Readout: Phase-reset applications, rapid sequencing ║\n", + "║ • PFB Readout: Multi-tone demodulation with 64 channels ║\n", + "║ ║\n", + "╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝\n", + "\n" + ] + } + ], + "source": [ + "print(\"\"\"\n", + "╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗\n", + "║ BEST PRACTICES SUMMARY ║\n", + "╠══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ ║\n", + "║ ✓ Always calibrate electrical delay before precision phase measurements ║\n", + "║ ✓ Use muxed generators + PFB readout for multi-tone experiments ║\n", + "║ ✓ In tProc v2, specify ABSOLUTE frequencies (not IFs) ║\n", + "║ ✓ Link generators to readouts with gen_ch parameter for automatic frequency matching ║\n", + "║ ✓ Use dynamic readouts for frequency sweeps to save configuration time ║\n", + "║ ✓ Keep pulse lengths within BRAM constraints (< 2^15 samples @ 1ns sample rate = 32.768 µs) ║\n", + "║ ✓ Use software averaging (reps parameter) for noise reduction ║\n", + "║ ✓ Monitor IQ offsets and apply corrections when necessary ║\n", + "║ ✓ Test new configurations with low power and short pulses first ║\n", + "║ ✓ Use progress=True for long acquisitions to monitor status ║\n", + "║ ║\n", + "╠══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ WHEN TO USE EACH TOOL ║\n", + "╠══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ ║\n", + "║ • Full-Speed Generator: Single tone, maximum bandwidth, simple pulses ║\n", + "║ • Interpolated Generator: Fine frequency resolution, shaped pulses ║\n", + "║ • Muxed Generators: Multiple phase-coherent tones ║\n", + "║ • Standard Readout: Fixed-frequency averaging ║\n", + "║ • Dynamic Readout: Frequency sweeps, calibration ║\n", + "║ • Fast Dynamic Readout: Phase-reset applications, rapid sequencing ║\n", + "║ • PFB Readout: Multi-tone demodulation with 64 channels ║\n", + "║ ║\n", + "╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝\n", + "\"\"\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 12. Next Steps\n", + "\n", + "You have now explored the key advanced generator and readout blocks in tProc v2.\n", + "\n", + "Proceed to [`08_Hardware_Buffers.ipynb`](./08_Hardware_Buffers.ipynb) to learn about the DDR4 and MR buffers for high-speed data capture.\n", + "\n", + "**Key Takeaways:**\n", + "\n", + "1. **tProc v2 uses absolute frequencies** - no more manual IF calculations\n", + "2. **Link generators and readouts** with `gen_ch` for automatic frequency matching\n", + "3. **Calibrate electrical delay** for accurate phase measurements\n", + "4. **Choose the right tool** based on your application requirements\n", + "5. **Monitor hardware offsets** and apply corrections as needed\n", + "\n", + "**Additional Resources:**\n", + "- To learn about basic sequencing, proceed to [`01_Basic_Sequencing.ipynb`](./01_Basic_Sequencing.ipynb)\n", + "- For parameter sweeps, see [`02_Parameter_Sweeps.ipynb`](./02_Parameter_Sweeps.ipynb)\n", + "- For real-time feedback, see [`04_Real_Time_Feedback.ipynb`](./04_Real_Time_Feedback.ipynb)\n", + "- For multi-core synchronization, see [`10_Multi_Core_Synchronization.ipynb`](./10_Multi_Core_Synchronization.ipynb)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/source/tutorials/08_Hardware_Buffers.ipynb b/docs/source/tutorials/08_Hardware_Buffers.ipynb new file mode 100644 index 000000000..06e84c582 --- /dev/null +++ b/docs/source/tutorials/08_Hardware_Buffers.ipynb @@ -0,0 +1,661 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 08 - Hardware Buffers: DDR4 and MR\n", + "\n", + "**Objective:** Learn how to use the DDR4 buffer (for long-duration captures) and the MR (Multi-Rate) buffer (for fast, tProc-accessible captures). Understand when to use each buffer type." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%pybind11/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Standard imports\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import logging\n", + "\n", + "from qick import *\n", + "from qick.asm_v2 import AveragerProgramV2, QickSweep1D\n", + "\n", + "# Setup logging\n", + "logging.basicConfig(level=logging.INFO, format='%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s')\n", + "logging.getLogger(\"qick_processor\").setLevel(logging.WARNING)\n", + "\n", + "# Connect to the board (adjust the path to your firmware)\n", + "BITSTREAM_PATH = 'qick_216.bit'#'/path/to/your/firmware.bit' # <--- CHANGE THIS\n", + "soc = QickSoc(BITSTREAM_PATH)\n", + "soccfg = soc\n", + "\n", + "# Define hardware channels\n", + "GEN_CH = 0\n", + "RO_CH = 0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Understanding Hardware Buffers\n", + "\n", + "QICK provides two types of hardware buffers for capturing readout data:\n", + "\n", + "| Buffer | Size | Access | Best for |\n", + "| :--- | :--- | :--- | :--- |\n", + "| **DDR4 Buffer** | Very large (up to ~1 second of data) | Read from Python after experiment | Long acquisitions, many repetitions |\n", + "| **MR Buffer** | Small (typically 8192 samples) | Read by tProc during experiment | Fast feedback, real-time decision making |\n", + "\n", + "**Key concepts:**\n", + "- Both buffers capture **decimated** IQ data (after downconversion and filtering)\n", + "- You can enable one or both in the same experiment\n", + "- Data is written continuously; you must manage buffer overflow" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Capturing Data to DDR4 Buffer\n", + "\n", + "The DDR4 buffer is ideal for capturing long sequences or many repetitions. It stores data in the board's DDR4 memory, which can hold millions of samples." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "6fff0ae3d25a4a719b077421df619a43", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/60 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Captured 31599 IQ samples from DDR4 buffer\n", + "Total duration: 102.86 µs\n" + ] + } + ], + "source": [ + "class DDR4Program(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " \n", + " self.declare_gen(ch=gen_ch, nqz=1)\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'])\n", + "\n", + " # Define loops (outer = gain sweep, inner = phase sweep)\n", + " self.add_loop(\"gain_loop\", self.cfg[\"steps_gain\"])\n", + " self.add_loop(\"phase_loop\", self.cfg[\"steps_phase\"])\n", + "\n", + " # Define a Gaussian envelope\n", + " ramp_len = 0.2\n", + " self.add_gauss(ch=gen_ch, name=\"ramp\", \n", + " sigma=ramp_len/10, length=ramp_len, even_length=True)\n", + " \n", + " # Define a flat-top pulse with sweeps\n", + " self.add_pulse(ch=gen_ch, name=\"swept_pulse\", \n", + " style=\"flat_top\", envelope=\"ramp\",\n", + " freq=cfg['freq'], length=cfg['flat_len'],\n", + " phase=QickSweep1D(\"phase_loop\", 0, 360),\n", + " gain=QickSweep1D(\"gain_loop\", 0.1, 1.0))\n", + "\n", + " self.add_readoutconfig(ch=ro_ch, name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=gen_ch)\n", + " self.send_readoutconfig(ch=ro_ch, name=\"my_ro\", t=0)\n", + " \n", + " def _body(self, cfg):\n", + " self.pulse(ch=cfg['gen_ch'], name=\"swept_pulse\", t=0)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'],\n", + " ddr4=True, mr=False) # Enable DDR4, disable MR\n", + "\n", + "# Configuration for DDR4 capture\n", + "config_ddr4 = {\n", + " 'steps_gain': 4,\n", + " 'steps_phase': 5,\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500,\n", + " 'trig_time': 0.25,\n", + " 'ro_len': 0.35,\n", + " 'flat_len': 0.05,\n", + " 'ramp_len': 0.2\n", + "}\n", + "\n", + "# Arm the DDR4 buffer before running\n", + "# Each transfer (burst) is 256 decimated samples\n", + "n_transfers = 10000 # Total samples = 256 * n_transfers\n", + "soc.arm_ddr4(ch=RO_CH, nt=n_transfers)\n", + "\n", + "# Run the program\n", + "prog = DDR4Program(soccfg, reps=3, final_delay=1.0, cfg=config_ddr4, reps_innermost=True)\n", + "iq_list = prog.acquire(soc, rounds=1, progress=True)\n", + "\n", + "# Read data from DDR4 buffer\n", + "# Request more samples than we expect to ensure we get everything\n", + "iq_ddr4 = soc.get_ddr4(250)\n", + "t_ddr4 = prog.get_time_axis_ddr4(RO_CH, iq_ddr4)\n", + "\n", + "plt.figure(figsize=(12, 4))\n", + "plt.plot(t_ddr4, iq_ddr4[:,0], label='I')\n", + "plt.plot(t_ddr4, iq_ddr4[:,1], label='Q')\n", + "plt.xlabel('Time (µs)')\n", + "plt.ylabel('Amplitude (a.u.)')\n", + "plt.title('DDR4 Buffer Capture - Continuous IQ Trace')\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.show()\n", + "\n", + "print(f\"Captured {len(iq_ddr4)} IQ samples from DDR4 buffer\")\n", + "print(f\"Total duration: {t_ddr4[-1]:.2f} µs\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Explanation:**\n", + "- `arm_ddr4(ch, nt)` prepares the buffer. `nt` is the number of transfers (each transfer = 256 decimated samples)\n", + "- Setting `ddr4=True` in `trigger()` enables DDR4 capture\n", + "- `get_ddr4(n)` reads data from the buffer. Request extra samples to ensure you get everything\n", + "- The data is continuous across all shots and sweep steps, showing the loop order" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Capturing Data to MR Buffer\n", + "\n", + "The MR (Multi-Rate) buffer is smaller but accessible to the tProc, making it useful for feedback and fast processing." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "2f83ec782e5b4c7eb46641c7517ac753", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/1 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Captured 8184 IQ samples from MR buffer\n", + "MR-related config keys: ['buf_maxlen', 'avgbuf_type', 'avgbuf_revision', 'avgbuf_fullpath', 'avgbuf_version']\n", + " buf_maxlen: 1024\n", + " avgbuf_type: axis_avg_buffer\n", + " avgbuf_revision: 7\n", + " avgbuf_fullpath: axis_avg_buffer_0\n", + " avgbuf_version: 1.0\n" + ] + } + ], + "source": [ + "class MRBufferProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " \n", + " self.declare_gen(ch=gen_ch, nqz=1)\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'])\n", + "\n", + " # Define a simple constant pulse\n", + " self.add_pulse(ch=gen_ch, name=\"test_pulse\", \n", + " style=\"const\", \n", + " freq=cfg['freq'], length=cfg['pulse_len'],\n", + " phase=0, gain=1.0)\n", + "\n", + " self.add_readoutconfig(ch=ro_ch, name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=gen_ch)\n", + " self.send_readoutconfig(ch=ro_ch, name=\"my_ro\", t=0)\n", + " \n", + " def _body(self, cfg):\n", + " self.pulse(ch=cfg['gen_ch'], name=\"test_pulse\", t=0)\n", + " # Enable MR buffer only (ddr4=False, mr=True)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'],\n", + " ddr4=False, mr=True)\n", + "\n", + "# Configuration\n", + "config_mr = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500,\n", + " 'trig_time': 0.25,\n", + " 'ro_len': 0.35,\n", + " 'pulse_len': 0.05\n", + "}\n", + "\n", + "# Arm the MR buffer\n", + "soc.arm_mr(ch=RO_CH)\n", + "\n", + "# Run the program\n", + "prog = MRBufferProgram(soccfg, reps=1, final_delay=0.5, cfg=config_mr)\n", + "iq_list = prog.acquire(soc, rounds=1)\n", + "\n", + "# Read data from MR buffer\n", + "iq_mr = soc.get_mr()\n", + "t_mr = prog.get_time_axis_mr(RO_CH, iq_mr)\n", + "\n", + "plt.figure(figsize=(12, 4))\n", + "plt.plot(t_mr, iq_mr[:,0], label='I')\n", + "plt.plot(t_mr, iq_mr[:,1], label='Q')\n", + "plt.plot(t_mr, np.abs(iq_mr.dot([1,1j])), label='Magnitude')\n", + "plt.xlabel('Time (µs)')\n", + "plt.ylabel('Amplitude (a.u.)')\n", + "plt.title('MR Buffer Capture')\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.show()\n", + "\n", + "print(f\"Captured {len(iq_mr)} IQ samples from MR buffer\")\n", + "ro_cfg = soccfg['readouts'][RO_CH]\n", + "mr_key = [k for k in ro_cfg.keys() if 'mr' in k.lower() or 'buf' in k.lower()]\n", + "print(f\"MR-related config keys: {mr_key}\")\n", + "for k in mr_key:\n", + " print(f\" {k}: {ro_cfg[k]}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Explanation:**\n", + "- `arm_mr(ch)` prepares the MR buffer\n", + "- Setting `mr=True` in `trigger()` enables MR capture\n", + "- `get_mr()` reads data from the buffer\n", + "- The MR buffer is smaller but faster and accessible to the tProc" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Using Both Buffers Simultaneously\n", + "\n", + "You can capture to both buffers at the same time. DDR4 provides long-duration storage, while MR provides fast tProc access." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "07f5f8d9f1034954a311350c94a4657b", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/10 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DDR4 captured 63599 samples\n", + "MR captured 8184 samples\n" + ] + } + ], + "source": [ + "class BothBuffersProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " \n", + " self.declare_gen(ch=gen_ch, nqz=1)\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'])\n", + "\n", + " self.add_pulse(ch=gen_ch, name=\"test_pulse\", \n", + " style=\"const\", \n", + " freq=cfg['freq'], length=cfg['pulse_len'],\n", + " phase=0, gain=1.0)\n", + "\n", + " self.add_readoutconfig(ch=ro_ch, name=\"my_ro\", \n", + " freq=cfg['freq'], gen_ch=gen_ch)\n", + " self.send_readoutconfig(ch=ro_ch, name=\"my_ro\", t=0)\n", + " \n", + " def _body(self, cfg):\n", + " self.pulse(ch=cfg['gen_ch'], name=\"test_pulse\", t=0)\n", + " # Enable both buffers\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'],\n", + " ddr4=True, mr=True)\n", + "\n", + "# Arm both buffers\n", + "soc.arm_ddr4(ch=RO_CH, nt=10000)\n", + "soc.arm_mr(ch=RO_CH)\n", + "\n", + "# Run 10 repetitions to fill buffers\n", + "prog = BothBuffersProgram(soccfg, reps=10, final_delay=0.5, cfg=config_mr)\n", + "iq_list = prog.acquire(soc, rounds=1)\n", + "\n", + "# Read both buffers\n", + "iq_ddr4 = soc.get_ddr4(500)\n", + "iq_mr = soc.get_mr()\n", + "\n", + "t_ddr4 = prog.get_time_axis_ddr4(RO_CH, iq_ddr4)\n", + "t_mr = prog.get_time_axis_mr(RO_CH, iq_mr)\n", + "\n", + "fig, axes = plt.subplots(2, 1, figsize=(12, 8))\n", + "\n", + "axes[0].plot(t_ddr4, iq_ddr4[:,0], label='I (DDR4)')\n", + "axes[0].plot(t_ddr4, iq_ddr4[:,1], label='Q (DDR4)')\n", + "axes[0].set_xlabel('Time (µs)')\n", + "axes[0].set_ylabel('Amplitude (a.u.)')\n", + "axes[0].set_title('DDR4 Buffer - Long Capture')\n", + "axes[0].legend()\n", + "axes[0].grid(True)\n", + "\n", + "axes[1].plot(t_mr, iq_mr[:,0], label='I (MR)')\n", + "axes[1].plot(t_mr, iq_mr[:,1], label='Q (MR)')\n", + "axes[1].set_xlabel('Time (µs)')\n", + "axes[1].set_ylabel('Amplitude (a.u.)')\n", + "axes[1].set_title('MR Buffer - Single Shot Detail')\n", + "axes[1].legend()\n", + "axes[1].grid(True)\n", + "\n", + "plt.tight_layout()\n", + "plt.show()\n", + "\n", + "print(f\"DDR4 captured {len(iq_ddr4)} samples\")\n", + "print(f\"MR captured {len(iq_mr)} samples\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. Analyzing Buffer Data with FFT\n", + "\n", + "You can perform frequency domain analysis on buffer data to examine signal spectra." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
      " + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Signal peak: -124.997 MHz\n", + "Image peak: +124.997 MHz (expected conjugate)\n", + "Image rejection: 37.5 dB (higher = better IQ balance)\n", + "\n", + "Aliased from: 182.203 or 489.403 MHz\n" + ] + } + ], + "source": [ + "from numpy.fft import fft, fftfreq, fftshift\n", + "import numpy as np\n", + "\n", + "iq_mr = soc.get_mr()\n", + "# Treat as true complex only if hardware produces quadrature — \n", + "# here col 0 and col 1 are two real ADC channels, so keep separate\n", + "signal_i = iq_mr[:, 0].astype(float)\n", + "signal_q = iq_mr[:, 1].astype(float)\n", + "\n", + "# Remove DC\n", + "signal_i -= signal_i.mean()\n", + "signal_q -= signal_q.mean()\n", + "\n", + "# Form complex and apply Hann window\n", + "N = len(signal_i)\n", + "window = np.hanning(N)\n", + "complex_signal = (signal_i + 1j * signal_q) * window\n", + "\n", + "# FFT\n", + "spectrum = fftshift(fft(complex_signal))\n", + "freqs = fftshift(fftfreq(N, d=1/fs_mr)) # MHz\n", + "psd = np.abs(spectrum)**2 / (fs_mr * np.sum(window**2)) # proper normalization\n", + "\n", + "plt.figure(figsize=(12, 5))\n", + "plt.semilogy(freqs, psd)\n", + "plt.xlabel('Frequency (MHz)')\n", + "plt.ylabel('Power Spectral Density')\n", + "plt.title(f'MR Buffer Spectrum (fs = {fs_mr} MHz, N = {N})')\n", + "plt.grid(True)\n", + "plt.tight_layout()\n", + "plt.show()\n", + "\n", + "# Report peaks excluding DC\n", + "dc_mask = np.abs(freqs) > 10\n", + "peak_idx = np.argmax(psd[dc_mask])\n", + "peak_freq = freqs[dc_mask][peak_idx]\n", + "peak_power = psd[dc_mask][peak_idx]\n", + "\n", + "# Find image peak (opposite sign)\n", + "image_mask = (np.abs(freqs) > 10) & (np.abs(freqs + peak_freq) < 5)\n", + "image_power = np.max(psd[image_mask]) if image_mask.any() else None\n", + "\n", + "print(f\"Signal peak: {peak_freq:+.3f} MHz\")\n", + "print(f\"Image peak: {-peak_freq:+.3f} MHz (expected conjugate)\")\n", + "if image_power:\n", + " imbalance_db = 10 * np.log10(peak_power / image_power)\n", + " print(f\"Image rejection: {imbalance_db:.1f} dB (higher = better IQ balance)\")\n", + "print(f\"\\nAliased from: {peak_freq + fs_mr:.3f} or {peak_freq + 2*fs_mr:.3f} MHz\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 7. Buffer Management Tips\n", + "\n", + "**Buffer Sizing:**\n", + "- DDR4: `nt` = number of transfers. Each transfer = 256 decimated samples\n", + "- MR: Fixed size (varies by firmware, typically 8192 samples)\n", + "- Both buffers are circular; old data is overwritten\n", + "\n", + "**Estimating buffer needs:**\n", + "```python\n", + "# For a program with:\n", + "# - reps = N\n", + "# - sweep_steps = M\n", + "# - readout_length = L (samples)\n", + "# Total samples = N * M * L\n", + "# Transfers needed = ceil(total_samples / 256)\n", + "```\n", + "\n", + "**Best practices:**\n", + "1. **Arm buffers before running the program** - They start capturing immediately\n", + "2. **Request extra samples when reading** - Use `get_ddr4(n)` with n larger than expected\n", + "3. **Use `get_time_axis_*` methods** - They compute the correct time axis for each buffer type\n", + "4. **Clear buffers between experiments** - Old data may persist" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# Example: Clearing buffers between experiments\n", + "def clear_buffers(soc, ro_ch):\n", + " \"\"\"Clear DDR4 and MR buffers by re-arming them with 0 transfers.\"\"\"\n", + " soc.arm_ddr4(ch=ro_ch, nt=0)\n", + " soc.arm_mr(ch=ro_ch)\n", + " print(\"Buffers cleared\")\n", + "\n", + "# clear_buffers(soc, RO_CH)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 8. Summary\n", + "\n", + "You have learned:\n", + "- The difference between DDR4 and MR buffers\n", + "- How to capture data to the DDR4 buffer for long acquisitions\n", + "- How to capture data to the MR buffer for fast, tProc-accessible data\n", + "- How to use both buffers simultaneously\n", + "- How to perform frequency analysis on buffer data\n", + "- Best practices for buffer management\n", + "\n", + "**When to use each buffer:**\n", + "- **DDR4:** Long acquisitions, many repetitions, post-processing analysis\n", + "- **MR:** Fast feedback, real-time decisions, single-shot analysis\n", + "- **Both:** When you need both long-term storage and real-time access\n", + "\n", + "**Next steps:** Proceed to [`09_Appendix_Tips_And_Limits.ipynb`](./09_Appendix_Tips_And_Limits.ipynb) for a reference guide on common pitfalls, hardware limits, and debugging tips." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/source/tutorials/09_Appendix_Tips_And_Limits.ipynb b/docs/source/tutorials/09_Appendix_Tips_And_Limits.ipynb new file mode 100644 index 000000000..f80758de1 --- /dev/null +++ b/docs/source/tutorials/09_Appendix_Tips_And_Limits.ipynb @@ -0,0 +1,824 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 09 - Appendix: Tips, Limits, and Troubleshooting\n", + "\n", + "**Objective:** This reference notebook covers common pitfalls, hardware limits, debugging techniques, and advanced parameters for tProc v2 programs. Use this as a reference when things don't work as expected." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%pybind11/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Standard imports\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import logging\n", + "\n", + "from qick import *\n", + "from qick.asm_v2 import AveragerProgramV2, QickSweep1D, AsmV2\n", + "\n", + "# Setup logging (set to DEBUG for detailed output)\n", + "logging.basicConfig(level=logging.INFO, format='%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s')\n", + "logging.getLogger(\"qick_processor\").setLevel(logging.WARNING)\n", + "\n", + "# Connect to the board (adjust the path to your firmware)\n", + "BITSTREAM_PATH = 'qick_216.bit'#'/path/to/your/firmware.bit' # <--- CHANGE THIS\n", + "soc = QickSoc(BITSTREAM_PATH)\n", + "soccfg = soc\n", + "\n", + "# Define hardware channels\n", + "GEN_CH = 0\n", + "RO_CH = 0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. tProc Hardware Limits\n", + "\n", + "Understanding the tProc's limitations will help you design programs that fit within hardware constraints." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== tProc Configuration ===\n", + "Program Memory: 1024 words\n", + "Data Memory: 1024 words\n", + "Waveform Memory: 256 words\n", + "Core Clock: 200.00000000000003 MHz\n", + "Timing Clock: 614.4 MHz\n", + "tProc Version: 2.0\n", + "Revision: 21\n", + "Has LFSR: True\n", + "Has Divider: False\n", + "Has Arith: False\n" + ] + } + ], + "source": [ + "# Display tProc configuration from firmware\n", + "print(\"=== tProc Configuration ===\")\n", + "if hasattr(soccfg, 'tproc'):\n", + " print(f\"Program Memory: {soccfg.tproc['pmem_size']} words\")\n", + " print(f\"Data Memory: {soccfg.tproc['dmem_size']} words\")\n", + " print(f\"Waveform Memory: {soccfg.tproc['wmem_size']} words\")\n", + " print(f\"Core Clock: {soccfg.tproc['f_core']} MHz\")\n", + " print(f\"Timing Clock: {soccfg.tproc['f_time']} MHz\")\n", + " print(f\"tProc Version: {soccfg.tproc['version']}\")\n", + " print(f\"Revision: {soccfg.tproc['revision']}\")\n", + " print(f\"Has LFSR: {bool(soccfg.tproc['has_lfsr'])}\")\n", + " print(f\"Has Divider: {bool(soccfg.tproc['has_divider'])}\")\n", + " print(f\"Has Arith: {bool(soccfg.tproc['has_arith'])}\")\n", + "else:\n", + " print(\"tProc info not available in soccfg\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.1 Program Memory Limit (4096 words)\n", + "\n", + "Each tProc instruction occupies 72 bits (9 bytes). Complex programs with many loops and sweeps can approach this limit.\n", + "\n", + "**How to check program size:**" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Program size: 17 instructions\n", + "Memory usage: 1.7%\n" + ] + } + ], + "source": [ + "# Create a simple program to check its size\n", + "class SizeTestProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"test\", style=\"const\",\n", + " freq=100, length=0.1, phase=0, gain=1.0)\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"ro\", freq=100, gen_ch=cfg['gen_ch'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"ro\", t=0)\n", + " def _body(self, cfg):\n", + " self.pulse(ch=cfg['gen_ch'], name=\"test\", t=0)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=0.25)\n", + "\n", + "config = {'gen_ch': GEN_CH, 'ro_ch': RO_CH, 'ro_len': 0.5}\n", + "prog = SizeTestProgram(soccfg, reps=1, final_delay=0.5, cfg=config)\n", + "prog.compile()\n", + "\n", + "print(f\"Program size: {len(prog.binprog['pmem'])} instructions\")\n", + "print(f\"Memory usage: {len(prog.binprog['pmem']) / soccfg.tproc['pmem_size'] * 100:.1f}%\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.2 Label Limit (2048 instruction offset)\n", + "\n", + "Jump instructions use 11 bits for address literals, limiting forward jumps to 2048 instructions. This affects loops and conditionals.\n", + "\n", + "**Workarounds:**\n", + "- Keep your program compact\n", + "- Use `reps_innermost=True` for large sweeps (loops are nested differently)\n", + "- Break large programs into multiple smaller ones" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.3 Time Limits (32-bit signed integers)\n", + "\n", + "Timing parameters use 32-bit signed integers. The maximum time depends on the timing clock frequency." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Maximum delay: 3495253 µs (3.5 seconds)\n" + ] + } + ], + "source": [ + "timing_clk_MHz = soccfg.tproc['f_time'] # e.g., 491.52 MHz\n", + "max_time_us = (2**31 - 1) / timing_clk_MHz\n", + "print(f\"Maximum delay: {max_time_us:.0f} µs ({max_time_us/1e6:.1f} seconds)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For most experiments, this is not a limiting factor." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Common Errors and Solutions\n", + "\n", + "### 3.1 Pulse Collision Warnings\n", + "\n", + "**Warning:** `Pulse {name} overlaps with previous pulse`\n", + "\n", + "**Cause:** A pulse is scheduled before the previous pulse has finished.\n", + "\n", + "**Solution:** Use `delay_auto()` to ensure proper spacing.\n", + "\n", + "```python\n", + "# Wrong:\n", + "self.pulse(ch=gen_ch, name=\"pulse1\", t=0)\n", + "self.pulse(ch=gen_ch, name=\"pulse2\", t=0.3) # May overlap\n", + "\n", + "# Correct:\n", + "self.pulse(ch=gen_ch, name=\"pulse1\", t=0)\n", + "self.delay_auto(gap=0.1) # Wait for pulse1 to finish + 0.1 µs\n", + "self.pulse(ch=gen_ch, name=\"pulse2\", t=0)\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2 Readout Latency Mismatch\n", + "\n", + "**Symptom:** Feedback readout values don't match buffered readout values.\n", + "\n", + "**Cause:** `read_wait` is too short; the tProc reads stale data.\n", + "\n", + "**Solution:** Increase `read_wait` until values match (see Notebook 04)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.3 Sweep Value Quantization\n", + "\n", + "**Symptom:** Swept values don't match the requested range exactly.\n", + "\n", + "**Cause:** Hardware parameters have limited precision (e.g., gain is 15-bit, phase is 32-bit).\n", + "\n", + "**Solution:** Use `get_pulse_param()` to retrieve actual values for accurate analysis." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requested vs Actual Gains:\n", + " 0.0000 -> 0.0000\n", + " 0.1111 -> 0.1111\n", + " 0.2222 -> 0.2222\n", + " 0.3333 -> 0.3333\n", + " 0.4444 -> 0.4445\n" + ] + } + ], + "source": [ + "# Example: Check quantization effects\n", + "requested_gains = np.linspace(0, 1, 10)\n", + "\n", + "# In a real program, you would do:\n", + "# actual_gains = prog.get_pulse_param('pulse', 'gain', as_array=True)\n", + "\n", + "# Simulate quantization (15-bit gain)\n", + "max_gain_int = 32766\n", + "actual_gains = np.round(requested_gains * max_gain_int) / max_gain_int\n", + "\n", + "print(\"Requested vs Actual Gains:\")\n", + "for req, act in zip(requested_gains[:5], actual_gains[:5]):\n", + " print(f\" {req:.4f} -> {act:.4f}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.4 Buffer Overflow\n", + "\n", + "**Symptom:** Data appears truncated or corrupted.\n", + "\n", + "**Cause:** More data was captured than the buffer can hold.\n", + "\n", + "**Solution:** Increase buffer size or reduce acquisition length." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Required transfers: 5000.0\n" + ] + } + ], + "source": [ + "# Estimate required buffer size\n", + "reps = 100\n", + "sweep_steps = 50\n", + "readout_samples = 256 # decimated samples\n", + "total_samples = reps * sweep_steps * readout_samples\n", + "required_transfers = np.ceil(total_samples / 256)\n", + "print(f\"Required transfers: {required_transfers}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Debugging Techniques\n", + "\n", + "### 4.1 Enable Detailed Logging\n", + "\n", + "Set logging level to DEBUG to see detailed assembler output." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "DEBUG [tprocv2_assembler.py:1017] LIST2BIN: ##### LIST 2 BIN\n", + "DEBUG [tprocv2_assembler.py:1029] list2bin: translating {'CMD': 'NOP', 'P_ADDR': 0}\n", + "DEBUG [tprocv2_assembler.py:1029] list2bin: translating {'CMD': 'REG_WR', 'DST': 's12', 'SRC': 'imm', 'LIT': '#0', 'P_ADDR': 1, 'LINE': 1}\n", + "DEBUG [tprocv2_assembler.py:1029] list2bin: translating {'CMD': 'WPORT_WR', 'DST': '3', 'SRC': 'wmem', 'ADDR': '&1', 'TIME': '@0', 'P_ADDR': 2, 'LINE': 2}\n", + "DEBUG [tprocv2_assembler.py:1029] list2bin: translating {'CMD': 'TIME', 'C_OP': 'inc_ref', 'LIT': '#614', 'P_ADDR': 3, 'LINE': 3}\n", + "DEBUG [tprocv2_assembler.py:1029] list2bin: translating {'CMD': 'REG_WR', 'DST': 'r0', 'SRC': 'imm', 'LIT': '#0', 'P_ADDR': 4, 'LINE': 4}\n", + "DEBUG [tprocv2_assembler.py:1029] list2bin: translating {'CMD': 'WPORT_WR', 'DST': '0', 'SRC': 'wmem', 'ADDR': '&0', 'TIME': '@0', 'P_ADDR': 5, 'LINE': 6}\n", + "DEBUG [tprocv2_assembler.py:1029] list2bin: translating {'CMD': 'DPORT_WR', 'DST': '0', 'SRC': 'imm', 'DATA': '1', 'TIME': '@154', 'P_ADDR': 6, 'LINE': 7}\n", + "DEBUG [tprocv2_assembler.py:1029] list2bin: translating {'CMD': 'TRIG', 'SRC': 'set', 'DST': '0', 'TIME': '@154', 'P_ADDR': 7, 'LINE': 8}\n", + "DEBUG [tprocv2_assembler.py:1029] list2bin: translating {'CMD': 'DPORT_WR', 'DST': '0', 'SRC': 'imm', 'DATA': '0', 'TIME': '@164', 'P_ADDR': 8, 'LINE': 9}\n", + "DEBUG [tprocv2_assembler.py:1029] list2bin: translating {'CMD': 'TRIG', 'SRC': 'clr', 'DST': '0', 'TIME': '@164', 'P_ADDR': 9, 'LINE': 10}\n", + "DEBUG [tprocv2_assembler.py:1029] list2bin: translating {'CMD': 'WAIT', 'C_OP': 'time', 'TIME': '@462', 'P_ADDR': 10, 'LINE': 11}\n", + "DEBUG [tprocv2_assembler.py:1083] COMMAND_TRANSLATION: Command Wait add one more instruction 11\n", + "DEBUG [tprocv2_assembler.py:1029] list2bin: translating {'CMD': 'TIME', 'C_OP': 'inc_ref', 'LIT': '#769', 'P_ADDR': 12, 'LINE': 12}\n", + "DEBUG [tprocv2_assembler.py:1029] list2bin: translating {'CMD': 'REG_WR', 'DST': 's12', 'SRC': 'op', 'OP': 's12 + #1', 'P_ADDR': 13, 'LINE': 13}\n", + "DEBUG [tprocv2_assembler.py:1029] list2bin: translating {'CMD': 'TEST', 'OP': 'r0 - #0', 'P_ADDR': 14, 'LINE': 14}\n", + "DEBUG [tprocv2_assembler.py:1029] list2bin: translating {'CMD': 'JUMP', 'LABEL': 'reps', 'IF': 'NZ', 'WR': 'r0 op', 'OP': 'r0 + #1', 'P_ADDR': 15, 'LINE': 15, 'ADDR': '&5'}\n", + "DEBUG [tprocv2_assembler.py:1029] list2bin: translating {'CMD': 'JUMP', 'LABEL': 'HERE', 'P_ADDR': 16, 'LINE': 16, 'ADDR': '&16'}\n" + ] + } + ], + "source": [ + "# Enable debug logging\n", + "logging.getLogger(\"qick.tprocv2_assembler\").setLevel(logging.DEBUG)\n", + "\n", + "# Run a simple program to see debug output\n", + "class DebugProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"test\", style=\"const\",\n", + " freq=100, length=0.1, phase=0, gain=1.0)\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"ro\", freq=100, gen_ch=cfg['gen_ch'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"ro\", t=0)\n", + " def _body(self, cfg):\n", + " self.pulse(ch=cfg['gen_ch'], name=\"test\", t=0)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=0.25)\n", + "\n", + "config = {'gen_ch': GEN_CH, 'ro_ch': RO_CH, 'ro_len': 0.5}\n", + "prog = DebugProgram(soccfg, reps=1, final_delay=0.5, cfg=config)\n", + "\n", + "# Reset logging to INFO after debugging\n", + "logging.getLogger(\"qick.tprocv2_assembler\").setLevel(logging.WARNING)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 4.2 Inspect Program Structure\n", + "\n", + "Use `print(prog)` to see the compiled program structure." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "macros:\n", + "\tWriteReg(dst='s_core_w1', src=0)\n", + "\tConfigReadout(ch=0, name='ro', t=0, tag=None, t_params={'t': }, t_regs={'t': 0})\n", + "\tDelay(t=1.0, auto=True, gens=True, ros=True, tag=None, t_params={'t': }, t_regs={'t': 614})\n", + "\tOpenLoop(n=1, name='reps')\n", + "\tPulse(ch=0, name='test', t=0, tag=None, t_params={'t': }, t_regs={'t': 0})\n", + "\tTrigger(ros=[0], tts=[], pins=[0], t=0.25, width=0.016276041666666668, ddr4=False, mr=False, tag=None, t_params={'t': , 'width': }, t_regs={'t': 154, 'width': 10}, outdict=defaultdict(, {0: 1}), trigset={0})\n", + "\tWait(t=0, auto=True, gens=False, ros=True, tag=None, no_warn=True, t_params={'t': }, t_regs={'t': 462})\n", + "\tDelay(t=0.5, auto=True, gens=True, ros=True, tag=None, t_params={'t': }, t_regs={'t': 769})\n", + "\tIncReg(dst='s_core_w1', src=1)\n", + "\tCloseLoop()\n", + "\tEnd()\n", + "registers:\n", + "\treps: QickRegisterV2(addr=0, init=None)\n", + "pulses:\n", + "\ttest: QickPulse(waveforms=[Waveform(name='test_w0', freq=QickRawParam(par='freq', start=43690667, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=32766, spans={}, quantize=1, steps={}), length=QickRawParam(par='length', start=61, spans={}, quantize=1, steps={}), conf=9)])\n", + "\tro: QickPulse(waveforms=[Waveform(name='ro_w0', freq=QickRawParam(par='freq', start=-174762668, spans={}, quantize=-4, steps={}), phase=0, env=0, gain=0, length=3, conf=520)])\n", + "expanded ASM:\n", + "\t NOP \n", + "\t REG_WR s12 imm #0 \n", + "\t WPORT_WR p3 wmem [&1] @0 \n", + "\t TIME #614 inc_ref \n", + "\t REG_WR r0 imm #0 \n", + "\treps:\n", + "\t WPORT_WR p0 wmem [&0] @0 \n", + "\t DPORT_WR p0 imm 1 @154 \n", + "\t TRIG p0 set @154 \n", + "\t DPORT_WR p0 imm 0 @164 \n", + "\t TRIG p0 clr @164 \n", + "\t WAIT @462 time \n", + "\t TIME #769 inc_ref \n", + "\t REG_WR s12 op -op(s12 + #1) \n", + "\t TEST -op(r0 - #0) \n", + "\t JUMP reps -if(NZ) -wr(r0 op) -op(r0 + #1) \n", + "\t JUMP HERE \n" + ] + } + ], + "source": [ + "print(prog)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 4.3 Check Specific Macros\n", + "\n", + "Use `get_macro(tag)` to inspect individual instructions." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Program created with 12 macros\n", + "macros:\n", + "\tWriteReg(dst='s_core_w1', src=0)\n", + "\tConfigReadout(ch=0, name='ro', t=0, tag=None, t_params={'t': }, t_regs={'t': 0})\n", + "\tDelay(t=1.0, auto=True, gens=True, ros=True, tag=None, t_params={'t': }, t_regs={'t': 614})\n", + "\tOpenLoop(n=1, name='reps')\n", + "\tPulse(ch=0, name='test', t=0, tag=None, t_params={'t': }, t_regs={'t': 0})\n", + "\tDelay(t=0.1, auto=True, gens=True, ros=True, tag=None, t_params={'t': }, t_regs={'t': 122})\n", + "\tTrigger(ros=[0], tts=[], pins=[0], t=0.25, width=0.016276041666666668, ddr4=False, mr=False, tag=None, t_params={'t': , 'width': }, t_regs={'t': 154, 'width': 10}, outdict=defaultdict(, {0: 1}), trigset={0})\n", + "\tWait(t=0, auto=True, gens=False, ros=True, tag=None, no_warn=True, t_params={'t': }, t_regs={'t': 462})\n", + "\tDelay(t=0.5, auto=True, gens=True, ros=True, tag=None, t_params={'t': }, t_regs={'t': 769})\n", + "\tIncReg(dst='s_core_w1', src=1)\n", + "\tCloseLoop()\n", + "\tEnd()\n", + "registers:\n", + "\treps: QickRegisterV2(addr=0, init=None)\n", + "pulses:\n", + "\ttest: QickPulse(waveforms=[Waveform(name='test_w0', freq=QickRawParam(par='freq', start=43690667, spans={}, quantize=1, steps={}), phase=QickRawParam(par='phase', start=0, spans={}, quantize=1, steps={}), env=0, gain=QickRawParam(par='gain', start=32766, spans={}, quantize=1, steps={}), length=QickRawParam(par='length', start=61, spans={}, quantize=1, steps={}), conf=9)])\n", + "\tro: QickPulse(waveforms=[Waveform(name='ro_w0', freq=QickRawParam(par='freq', start=-174762668, spans={}, quantize=-4, steps={}), phase=0, env=0, gain=0, length=3, conf=520)])\n", + "expanded ASM:\n", + "\t NOP \n", + "\t REG_WR s12 imm #0 \n", + "\t WPORT_WR p3 wmem [&1] @0 \n", + "\t TIME #614 inc_ref \n", + "\t REG_WR r0 imm #0 \n", + "\treps:\n", + "\t WPORT_WR p0 wmem [&0] @0 \n", + "\t TIME #122 inc_ref \n", + "\t DPORT_WR p0 imm 1 @154 \n", + "\t TRIG p0 set @154 \n", + "\t DPORT_WR p0 imm 0 @164 \n", + "\t TRIG p0 clr @164 \n", + "\t WAIT @462 time \n", + "\t TIME #769 inc_ref \n", + "\t REG_WR s12 op -op(s12 + #1) \n", + "\t TEST -op(r0 - #0) \n", + "\t JUMP reps -if(NZ) -wr(r0 op) -op(r0 + #1) \n", + "\t JUMP HERE \n" + ] + } + ], + "source": [ + "# Create a program with tags to inspect macros\n", + "class TaggedProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"test\", style=\"const\",\n", + " freq=100, length=0.1, phase=0, gain=1.0)\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"ro\", freq=100, gen_ch=cfg['gen_ch'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"ro\", t=0)\n", + "\n", + " def _body(self, cfg):\n", + " self.pulse(ch=cfg['gen_ch'], name=\"test\", t=0)\n", + " self.delay_auto(0.1) # sin keyword 'gap', sin 'tag'\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=0.25)\n", + "\n", + "config = {'gen_ch': GEN_CH, 'ro_ch': RO_CH, 'ro_len': 0.5}\n", + "prog_tagged = TaggedProgram(soccfg, reps=1, final_delay=0.5, cfg=config)\n", + "print(\"Program created with\", len(prog_tagged.macro_list), \"macros\")\n", + "print(prog_tagged) # inspect the full structure" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "All macros:\n", + " [0] WriteReg: WriteReg(dst='s_core_w1', src=0)\n", + " [1] ConfigReadout: ConfigReadout(ch=0, name='ro', t=0, tag=None, t_params={'t': }, t_regs={'t': 0})\n", + " [2] Delay: Delay(t=1.0, auto=True, gens=True, ros=True, tag=None, t_params={'t': }, t_regs={'t': 614})\n", + " [3] OpenLoop: OpenLoop(n=1, name='reps')\n", + " [4] Pulse: Pulse(ch=0, name='test', t=0, tag=None, t_params={'t': }, t_regs={'t': 0})\n", + " [5] Delay: Delay(t=0.1, auto=True, gens=True, ros=True, tag=None, t_params={'t': }, t_regs={'t': 122})\n", + " [6] Trigger: Trigger(ros=[0], tts=[], pins=[0], t=0.25, width=0.016276041666666668, ddr4=False, mr=False, tag=None, t_params={'t': , 'width': }, t_regs={'t': 154, 'width': 10}, outdict=defaultdict(, {0: 1}), trigset={0})\n", + " [7] Wait: Wait(t=0, auto=True, gens=False, ros=True, tag=None, no_warn=True, t_params={'t': }, t_regs={'t': 462})\n", + " [8] Delay: Delay(t=0.5, auto=True, gens=True, ros=True, tag=None, t_params={'t': }, t_regs={'t': 769})\n", + " [9] IncReg: IncReg(dst='s_core_w1', src=1)\n", + " [10] CloseLoop: CloseLoop()\n", + " [11] End: End()\n", + "\n", + "Pulse macros: [(4, Pulse(ch=0, name='test', t=0, tag=None, t_params={'t': }, t_regs={'t': 0}))]\n", + "Delay macros: [(2, Delay(t=1.0, auto=True, gens=True, ros=True, tag=None, t_params={'t': }, t_regs={'t': 614})), (5, Delay(t=0.1, auto=True, gens=True, ros=True, tag=None, t_params={'t': }, t_regs={'t': 122})), (8, Delay(t=0.5, auto=True, gens=True, ros=True, tag=None, t_params={'t': }, t_regs={'t': 769}))]\n", + "Trigger macros: [(6, Trigger(ros=[0], tts=[], pins=[0], t=0.25, width=0.016276041666666668, ddr4=False, mr=False, tag=None, t_params={'t': , 'width': }, t_regs={'t': 154, 'width': 10}, outdict=defaultdict(, {0: 1}), trigset={0}))]\n" + ] + } + ], + "source": [ + "# Inspect acros from program\n", + "print(\"All macros:\")\n", + "for i, macro in enumerate(prog_tagged.macro_list):\n", + " print(f\" [{i}] {type(macro).__name__}: {macro}\")\n", + "\n", + "# Buscar por tipo en lugar de por tag\n", + "def get_macros_by_type(prog, macro_type_name):\n", + " return [(i, m) for i, m in enumerate(prog.macro_list) \n", + " if type(m).__name__ == macro_type_name]\n", + "\n", + "print(\"\\nPulse macros:\", get_macros_by_type(prog_tagged, 'Pulse'))\n", + "print(\"Delay macros:\", get_macros_by_type(prog_tagged, 'Delay'))\n", + "print(\"Trigger macros:\", get_macros_by_type(prog_tagged, 'Trigger'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 4.4 Verify Pulse Parameters\n", + "\n", + "Use `get_pulse_param()` to check actual parameters after quantization." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Phase values: [-180. -90. 0. 90. 180.]\n", + "Gain values: [0. 0.24998474 0.49996948 0.74995422 0.99993896]\n" + ] + } + ], + "source": [ + "# In a sweep program, you can check all swept values\n", + "class SweepCheckProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + " self.add_loop(\"sweep\", cfg['steps'])\n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"test\", style=\"const\",\n", + " freq=cfg['freq'], length=0.1,\n", + " phase=QickSweep1D(\"sweep\", -180, 180),\n", + " gain=QickSweep1D(\"sweep\", 0, 1))\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"ro\", freq=cfg['freq'], gen_ch=cfg['gen_ch'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"ro\", t=0)\n", + " def _body(self, cfg):\n", + " self.pulse(ch=cfg['gen_ch'], name=\"test\", t=0)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=0.25)\n", + "\n", + "config_check = {'gen_ch': GEN_CH, 'ro_ch': RO_CH, 'freq': 100, 'steps': 5, 'ro_len': 0.5}\n", + "prog_check = SweepCheckProgram(soccfg, reps=1, final_delay=0.5, cfg=config_check)\n", + "\n", + "phases = prog_check.get_pulse_param('test', 'phase', as_array=True)\n", + "gains = prog_check.get_pulse_param('test', 'gain', as_array=True)\n", + "\n", + "print(f\"Phase values: {phases}\")\n", + "print(f\"Gain values: {gains}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Advanced Parameters\n", + "\n", + "### 5.1 The `reps_innermost` Parameter\n", + "\n", + "By default, the `reps` loop (experiment repetitions) is the **outermost** loop. This reduces sensitivity to slow drifts." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Default (reps outermost): Sweep completes all steps before next repetition\n", + "Alternative (reps innermost): All repetitions at each sweep step before moving to next step\n" + ] + } + ], + "source": [ + "class LoopOrderProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + " self.add_loop(\"sweep\", 3)\n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"test\", style=\"const\",\n", + " freq=100, length=0.1, phase=0,\n", + " gain=QickSweep1D(\"sweep\", 0, 1))\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"ro\", freq=100, gen_ch=cfg['gen_ch'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"ro\", t=0)\n", + " def _body(self, cfg):\n", + " self.pulse(ch=cfg['gen_ch'], name=\"test\", t=0)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=0.25)\n", + "\n", + "config_loop = {'gen_ch': GEN_CH, 'ro_ch': RO_CH, 'ro_len': 0.5}\n", + "\n", + "# Default: reps outermost\n", + "prog_default = LoopOrderProgram(soccfg, reps=4, final_delay=0.5, cfg=config_loop, reps_innermost=False)\n", + "\n", + "# Alternative: reps innermost\n", + "prog_innermost = LoopOrderProgram(soccfg, reps=4, final_delay=0.5, cfg=config_loop, reps_innermost=True)\n", + "\n", + "print(\"Default (reps outermost): Sweep completes all steps before next repetition\")\n", + "print(\"Alternative (reps innermost): All repetitions at each sweep step before moving to next step\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 5.2 The `final_delay` and `initial_delay` Parameters\n", + "\n", + "These parameters add automatic delays at the beginning and end of each shot." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Program with 5 µs initial delay and 10 µs final delay per shot\n" + ] + } + ], + "source": [ + "# initial_delay: added after _initialize() completes\n", + "# final_delay: added at the end of each shot before the next repetition\n", + "\n", + "prog_with_delays = LoopOrderProgram(soccfg, reps=2, final_delay=10.0, \n", + " cfg=config_loop, initial_delay=5.0)\n", + "print(\"Program with 5 µs initial delay and 10 µs final delay per shot\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. Quick Reference: Parameter Quantization\n", + "\n", + "| Parameter | Units | Resolution | Range |\n", + "| :--- | :--- | :--- | :--- |\n", + "| Frequency | MHz | Depends on DDS bit-width | ±DDS_range |\n", + "| Phase | degrees | 360/2^32 ≈ 8.4e-8° | 0-360° (wraps) |\n", + "| Gain | linear | 1/32766 ≈ 3e-5 | 0 to 1 |\n", + "| Time/Duration | µs | 1/timing_clock (≈2 ns) | ±2^31 ticks |\n", + "| Length (const pulse) | µs | Same as time | >0 |\n", + "| Length (flat-top flat) | µs | Same as time | >0 |" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 7. Troubleshooting Checklist\n", + "\n", + "When an experiment doesn't work as expected, check these items in order:\n", + "\n", + "1. **Hardware Connection** - Is the board connected? Does `soccfg` show correct configuration?\n", + "2. **Firmware Version** - Is the firmware compatible with your QICK version?\n", + "3. **Channel Configuration** - Are the generator and readout channels correct?\n", + "4. **Pulse Parameters** - Are frequency, gain, and length within valid ranges?\n", + "5. **Timeline** - Are pulses colliding? Use `delay_auto()` for spacing.\n", + "6. **Readout Latency** - Is `read_wait` properly tuned for feedback?\n", + "7. **Buffer Arm** - Are buffers armed before running? Do they have enough capacity?\n", + "8. **Program Size** - Is the program exceeding tProc memory limits?\n", + "9. **Logging** - Set logging to DEBUG and look for warnings or errors.\n", + "10. **Data Retrieval** - Are you using the correct time axis for your buffer type?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 8. Summary\n", + "\n", + "This reference notebook covers:\n", + "- Hardware limits of the tProc (program memory, labels, time ranges)\n", + "- Common errors and their solutions\n", + "- Debugging techniques (logging, program inspection, parameter verification)\n", + "- Advanced parameters (`reps_innermost`, `final_delay`, `initial_delay`)\n", + "- Parameter quantization reference table\n", + "- Troubleshooting checklist\n", + "\n", + "**Next Steps:**\n", + "\n", + "- Proceed to [`10_Multi_Board_Synchronization.ipynb`](./10_Multi_Board_Synchronization.ipynb) to learn about how to connect and work with multiple boards inter-connected.\n", + "- Review the other notebooks in this series for detailed examples\n", + "- Refer to the [QICK Documentation](https://qick-docs.readthedocs.io/) for complete API reference\n", + "- Join the QICK community for support" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/source/tutorials/10_Multi_Board_Synchronization.ipynb b/docs/source/tutorials/10_Multi_Board_Synchronization.ipynb new file mode 100644 index 000000000..6de4c1dc9 --- /dev/null +++ b/docs/source/tutorials/10_Multi_Board_Synchronization.ipynb @@ -0,0 +1,867 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 10 - Multi-Board Synchronization\n", + "\n", + "**Objective:** Learn how to synchronize multiple QICK boards using external clock and external start signals. This notebook covers:\n", + "\n", + "- External clock configuration for frequency synchronization\n", + "- External start pins for tProc synchronization\n", + "- Leader-follower synchronization scheme\n", + "- Software synchronization for multi-board experiments\n", + "- Measuring inter-board jitter and timing accuracy\n", + "- Practical examples for tProc v1 and v2 firmwares\n", + "\n", + "**Prerequisites:**\n", + "- Two or more QICK boards\n", + "- Stable external reference clock (e.g., rubidium clock, 10 MHz reference)\n", + "- PMOD jumper wires for start signal connection\n", + "- Coaxial cables for RF loopback between boards\n", + "- Completed basic tutorials (00-05)\n", + "\n", + "**References:**\n", + "- QICK Documentation: https://docs.qick.dev\n", + "- Reference Clock: https://docs.qick.dev/latest/topics/reference_clock.html" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Overview\n", + "\n", + "QICK provides two key features for multi-board synchronization:\n", + "\n", + "1. **External Clock**: The clock reference chips on the RFSoC board can be configured to lock to an external reference.\n", + "\n", + "2. **External Start**: The tProc can be configured to wait for an external pulse before starting execution of a program.\n", + "\n", + "These features can be used together to run synchronized programs on multiple boards. The general idea:\n", + "\n", + "- All boards are locked to a common reference clock\n", + "- The \"leader\" board sends a pulse on one of the PMOD pins at the beginning of its program\n", + "- The \"follower\" boards are configured for external start, so their tProcs only start execution when the pulse arrives at the external-start pin (another PMOD pin)\n", + "- The jitter between boards is governed by the stability of the board clocks (sub-100 ps achievable)\n", + "\n", + "### Hardware Requirements\n", + "\n", + "```\n", + "┌─────────────────────────────────────────────────────────────────────────────┐\n", + "│ Multi-Board Synchronization │\n", + "├─────────────────────────────────────────────────────────────────────────────┤\n", + "│ │\n", + "│ ┌──────────┐ ┌───────────┐ │\n", + "│ │ QICK #1 │ PMOD0_0 ──► PMOD1_0 │ QICK #2 │────── │\n", + "│ │ (Leader) │ │ (Follower)│ | │\n", + "│ └────┬─────┘ └────┬──────┘ | │\n", + "│ │ │ | │\n", + "│ │ ┌─────────────────────────────────────┐ | │\n", + "│ └──►│ External Reference Clock │◄───┘ │\n", + "│ │ (e.g., 12.8 MHz for ZCU111) │ │\n", + "│ └─────────────────────────────────────┘ │\n", + "│ │\n", + "│ • Leader PMOD0_0 → Follower PMOD1_0 (start signal) │\n", + "│ • Coaxial cables for DAC→ADC loopback between boards │\n", + "│ • Shared external reference clock for frequency sync │\n", + "│ │\n", + "└─────────────────────────────────────────────────────────────────────────────┘\n", + "```\n", + "\n", + "**Important notes:**\n", + "- tProc v1 firmwares have always supported external start\n", + "- tProc v2 requires revision 24 or later for stable external start\n", + "- The phase relationship between tProc clocks is random; if you see a one-tick jitter (<10% probability), re-initialize the leader or follower\n", + "- This scheme works for multiple followers (just wire all PMOD1_0 pins to the leader's PMOD0_0)\n", + "- The jitter measurement technique here is limited by interpolation between decimated data points; for better measurements, use a scope or time-tagger readout" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Setup and Initialization" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Standard imports\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import time\n", + "import logging\n", + "import asyncio\n", + "import functools\n", + "\n", + "from qick import *\n", + "from qick.asm_v2 import AveragerProgramV2\n", + "\n", + "# Setup logging\n", + "logging.basicConfig(level=logging.INFO, format='%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s')\n", + "\n", + "# Import nest_asyncio for Jupyter compatibility\n", + "import nest_asyncio\n", + "nest_asyncio.apply()\n", + "\n", + "print(\"Setup complete.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.1 Connect to Multiple Boards via Pyro\n", + "\n", + "For multi-board experiments, we'll use Pyro to connect to each board independently. Start the Pyro servers on each board first:\n", + "\n", + "```python\n", + "# On each board (e.g., qick1 and qick2)\n", + "from qick.pyro import start_server\n", + "start_server(\n", + " ns_host=\"your_nameserver_host\",\n", + " ns_port=8888,\n", + " proxy_name=\"qick1\", # or \"qick2\"\n", + " external_clk=True, # Important: use external reference\n", + " adc_sample_rates={0:3072.0} # Optional: set ADC sample rate\n", + ")\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from qick.pyro import make_proxy\n", + "\n", + "# Connect to boards via Pyro (use your actual host IP and port)\n", + "NS_HOST = \"localhost\" # Change to your nameserver host\n", + "NS_PORT = 8888\n", + "\n", + "proxies = []\n", + "for name in ['qick1', 'qick2']:\n", + " proxies.append(make_proxy(ns_host=NS_HOST, ns_port=NS_PORT, proxy_name=name))\n", + "\n", + "# Display board configurations\n", + "for i, (soc, soccfg) in enumerate(proxies):\n", + " print(f\"\\n=== Board {i+1} ===\")\n", + " print(f\"Firmware: {soccfg.get('fw_version', 'Unknown')}\")\n", + " print(f\"tProc cores: {soc.num_tprocs}\")\n", + " print(f\"External clock: {soccfg.get('external_clk', False)}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.2 Utility Functions\n", + "\n", + "These helper functions will be used for data analysis." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_inphase(iq):\n", + " \"\"\"\n", + " Takes an IQ array, rotates it so the average is on the positive real axis,\n", + " and returns the real component.\n", + " This is the component of the data that's in phase with the signal.\n", + " Useful because unlike the magnitude, this is zero-centered in the absence of signal.\n", + " \"\"\"\n", + " x = iq.dot([1, 1j])\n", + " x_rotated = x * np.exp(-1j * np.angle(x.mean()))\n", + " return np.real(x_rotated)\n", + "\n", + "def find_edges(inphase, trim=7):\n", + " \"\"\"\n", + " Find rising and falling edges of a rectangular pulse.\n", + " Uses linear interpolation around a threshold, where the threshold is half the pulse height.\n", + " The pulse height is measured by finding the pulse, trimming the specified number of samples on either end, and averaging.\n", + " \n", + " Parameters:\n", + " - inphase: In-phase component of the signal\n", + " - trim: Number of samples to trim from pulse ends for height measurement\n", + " \n", + " Returns:\n", + " - rising: Rising edge time (interpolated)\n", + " - falling: Falling edge time (interpolated)\n", + " - flatheight: Average height of the pulse flat top\n", + " \"\"\"\n", + " # Find the mean height in the flat part of the pulse\n", + " x = inphase - 0.5 * inphase.max()\n", + " ispulse = (x > 0)\n", + " pulserange = (np.argmax(ispulse), ispulse.size - np.argmax(ispulse[::-1]))\n", + " flat = inphase[pulserange[0] + trim:pulserange[1] - trim]\n", + " flatheight = flat.mean()\n", + " \n", + " # Get a more precise estimate of the rising and falling edges\n", + " # Use linear interpolation between samples\n", + " x = inphase - 0.5 * flatheight\n", + " ispulse = (x > 0)\n", + " \n", + " # Indices of the samples after the rising/falling edges\n", + " rising = np.argmax(ispulse)\n", + " falling = ispulse.size - np.argmax(ispulse[::-1])\n", + " \n", + " # Linear interpolation between the points before/after the zero crossing\n", + " rising -= x[rising] / (x[rising] - x[rising - 1])\n", + " falling -= x[falling] / (x[falling] - x[falling - 1])\n", + " \n", + " return rising, falling, flatheight\n", + "\n", + "def plot_jitter(plot, x, y):\n", + " \"\"\"\n", + " Scatterplot two pulse times' deviation from the median.\n", + " Scales the axes to maintain a square aspect ratio.\n", + " \"\"\"\n", + " x = x - np.median(x)\n", + " y = y - np.median(y)\n", + " plot.plot(x, y, '.')\n", + " maxrange = max([np.abs(a).max() for a in [x, y]])\n", + " plot.set_xlim((-1.1 * maxrange, 1.1 * maxrange))\n", + " plot.set_ylim((-1.1 * maxrange, 1.1 * maxrange))\n", + "\n", + "print(\"Utility functions defined.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.3 Software Synchronization\n", + "\n", + "We need to run programs on multiple boards at the same time. The follower should enter external-start mode before the leader sends the start pulse. This requires software synchronization.\n", + "\n", + "For each program execution (\"round\"), we wait until all boards are ready to run, then run the round. This is done using the `step_rounds` argument to `acquire_decimated()`.\n", + "\n", + "For reference, this is how you'd use this when running a single board:\n", + "```python\n", + "prog.acquire(soc, start_src='internal', step_rounds=True)\n", + "while prog.finish_round():\n", + " prog.prepare_round()\n", + "iq_list = prog.finish_acquire()\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "async def wrap_round(loop, prog):\n", + " \"\"\"Wrapper for async round completion check.\"\"\"\n", + " result = await loop.run_in_executor(None, prog.finish_round)\n", + " return result\n", + "\n", + "async def run_multi_decimated(loop, proxies, progs, **kwargs):\n", + " \"\"\"\n", + " Run a set of programs on a multi-board setup, in decimated mode.\n", + " \n", + " Parameters:\n", + " - loop: asyncio event loop\n", + " - proxies: list of (soc, soccfg) tuples, leader first\n", + " - progs: list of programs, same order as proxies\n", + " - other arguments passed through to acquire_decimated\n", + " \n", + " Returns:\n", + " - List of acquired data from each program\n", + " \"\"\"\n", + " # Initialize all programs\n", + " for i, prog in enumerate(progs):\n", + " soc, soccfg = proxies[i]\n", + " start_src = 'internal' if i == 0 else 'external'\n", + " prog.acquire_decimated(soc,\n", + " start_src=start_src,\n", + " step_rounds=True,\n", + " **kwargs)\n", + " \n", + " # Execute rounds synchronously\n", + " while True:\n", + " async with asyncio.TaskGroup() as tg:\n", + " tasks = []\n", + " for prog in progs:\n", + " tasks.append(tg.create_task(wrap_round(loop, prog)))\n", + " \n", + " results = [task.result() for task in tasks]\n", + " if not any(results):\n", + " break\n", + " if not all(results):\n", + " raise RuntimeError(f\"Some done, some not: {results}\")\n", + " \n", + " for prog in progs:\n", + " prog.prepare_round()\n", + " \n", + " return [prog.finish_acquire() for prog in progs]\n", + "\n", + "print(\"Async wrapper functions defined.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. tProc v1 Example\n", + "\n", + "Start with tProc v1 because we know external start works. The standard firmware is fine.\n", + "\n", + "**Firmware requirements:**\n", + "- Any tProc v1 firmware with an external start pin - this is most firmwares\n", + "- For tProc v2, you need revision 24 or later\n", + "\n", + "**Channel configuration:**\n", + "- DAC 229_3 to ADC 224_0 (loopback within board)\n", + "- DAC 229_2 to ADC 224_1 (loopback between boards)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Channel configuration for tProc v1\n", + "GEN_CHS = [6, 5]\n", + "RO_CHS = [0, 1]\n", + "TRIG_TIME = 145 # tProc ticks\n", + "FREQ = 500 # MHz\n", + "\n", + "print(f\"Generator channels: {GEN_CHS}\")\n", + "print(f\"Readout channels: {RO_CHS}\")\n", + "print(f\"Frequency: {FREQ} MHz\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class LoopbackProgram(AveragerProgram):\n", + " \"\"\"\n", + " Loopback program for tProc v1.\n", + " Generates a pulse and measures it on the same board or across boards.\n", + " \"\"\"\n", + " def initialize(self):\n", + " cfg = self.cfg\n", + " for gen_ch in cfg[\"gen_chs\"]:\n", + " self.declare_gen(ch=gen_ch, nqz=1)\n", + " for ch in cfg[\"ro_chs\"]:\n", + " self.declare_readout(ch=ch, length=cfg[\"ro_len\"],\n", + " freq=cfg[\"freq\"], gen_ch=cfg[\"gen_chs\"][0])\n", + "\n", + " freq = self.freq2reg(cfg[\"freq\"], gen_ch=cfg[\"gen_chs\"][0], ro_ch=cfg[\"ro_chs\"][0])\n", + " phase = self.deg2reg(cfg[\"gen_phase\"], gen_ch=cfg[\"gen_chs\"][0])\n", + " gain = cfg[\"gen_gain\"]\n", + " \n", + " for gen_ch in cfg[\"gen_chs\"]:\n", + " # The minimum length for a waveform is 3 fabric ticks (48 DAC samples)\n", + " # Create a custom envelope with ramps\n", + " maxv = self.get_maxv(gen_ch)\n", + " idata = np.ones(6*16, dtype=np.int32) * maxv\n", + " idata[:cfg['ramp_nsamp']] = np.linspace(0, maxv, cfg['ramp_nsamp'], dtype=np.int32)\n", + " idata[:-cfg['ramp_nsamp']-1:-1] = np.linspace(0, maxv, cfg['ramp_nsamp'], dtype=np.int32)\n", + " qdata = np.zeros(6*16, dtype=np.int32)\n", + " self.add_envelope(ch=gen_ch, name=\"ramp\", idata=idata, qdata=qdata)\n", + " self.set_pulse_registers(ch=gen_ch, freq=freq, phase=phase, gain=gain,\n", + " style=\"flat_top\", length=cfg[\"pulse_len\"],\n", + " waveform='ramp')\n", + "\n", + " if cfg['send_start']:\n", + " self.synci(200) # give processor some time to set registers\n", + " self.trigger(pins=[0], t=0) # output a pulse on PMOD0_0, to trigger the follower\n", + " self.synci(cfg['leader_delay']) # give follower time to catch up\n", + " self.synci(200 + cfg['follower_delay']) # give processor some time to set registers\n", + " \n", + " def body(self):\n", + " self.trigger(adcs=self.cfg[\"ro_chs\"],\n", + " adc_trig_offset=self.cfg[\"adc_trig_offset\"])\n", + " for gen_ch in self.cfg[\"gen_chs\"]:\n", + " self.pulse(ch=gen_ch)\n", + " self.wait_all()\n", + " self.sync_all(self.us2cycles(self.cfg[\"relax_delay\"]))\n", + "\n", + "# Base configuration\n", + "config = {\n", + " \"gen_chs\": GEN_CHS,\n", + " \"ro_chs\": RO_CHS,\n", + " \"leader_delay\": 10, # tProc ticks\n", + " \"follower_delay\": 0, # tProc ticks\n", + " \"relax_delay\": 1.0, # us\n", + " \"gen_phase\": 0, # degrees\n", + " \"pulse_len\": 20, # gen ticks\n", + " \"ramp_nsamp\": 32, # DAC samples\n", + " \"ro_len\": 50, # RO ticks\n", + " \"gen_gain\": 30000, # DAC units\n", + " \"freq\": FREQ, # MHz\n", + " \"adc_trig_offset\": TRIG_TIME, # tProc ticks\n", + " \"send_start\": False,\n", + " \"reps\": 1,\n", + " \"soft_avgs\": 100\n", + "}\n", + "\n", + "print(\"Loopback program defined.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.1 Test One Board at a Time\n", + "\n", + "First, run each board independently to verify the setup." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "progs = []\n", + "config['send_start'] = False\n", + "\n", + "for i, (soc, soccfg) in enumerate(proxies):\n", + " progs.append(LoopbackProgram(soccfg, config))\n", + " \n", + "iq_lists = []\n", + "for i, (soc, soccfg) in enumerate(proxies):\n", + " print(f\"Acquiring data from board {i+1}...\")\n", + " iq_lists.append(progs[i].acquire_decimated(soc, progress=True))\n", + "\n", + "# Plot results\n", + "fig, axes = plt.subplots(len(iq_lists), 1, figsize=(15, 8))\n", + "if len(iq_lists) == 1:\n", + " axes = [axes]\n", + " \n", + "for i, iq_list in enumerate(iq_lists):\n", + " axes[i].set_title(f\"Board {i+1}\")\n", + " for ii, iq in enumerate(iq_list):\n", + " axes[i].plot(iq[:, 0], label=f\"I, ADC {config['ro_chs'][ii]}\", alpha=0.7)\n", + " axes[i].plot(iq[:, 1], label=f\"Q, ADC {config['ro_chs'][ii]}\", alpha=0.7)\n", + " axes[i].plot(np.abs(iq.dot([1, 1j])), label=f\"Mag, ADC {config['ro_chs'][ii]}\", alpha=0.7)\n", + " axes[i].set_ylabel(\"Amplitude (a.u.)\")\n", + " axes[i].set_xlabel(\"Sample\")\n", + " axes[i].legend()\n", + " axes[i].grid(True)\n", + " \n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2 Synchronized Multi-Board Acquisition\n", + "\n", + "Now run the boards together. Adjust `leader_delay` to align the pulses as desired.\n", + "\n", + "If the boards are well synchronized, the pulses should all lie on top of each other." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Adjust leader_delay for synchronization\n", + "# Experiment with this value to align the pulses\n", + "config['leader_delay'] = 14 # tProc ticks\n", + "\n", + "# Create programs\n", + "progs = []\n", + "for i, (soc, soccfg) in enumerate(proxies):\n", + " config['send_start'] = (i == 0) # Only leader sends start pulse\n", + " progs.append(LoopbackProgram(soccfg, config))\n", + "\n", + "# Run synchronized acquisition\n", + "loop = asyncio.get_event_loop()\n", + "iq_lists = loop.run_until_complete(\n", + " run_multi_decimated(loop, proxies, progs, progress=True, rounds=100)\n", + ")\n", + "\n", + "# Plot results\n", + "fig, axes = plt.subplots(len(progs), 1, figsize=(15, 10))\n", + "if len(progs) == 1:\n", + " axes = [axes]\n", + " \n", + "colors = ['blue', 'red']\n", + "for i, prog in enumerate(progs):\n", + " axes[i].set_title(['Leader', 'Follower'][i])\n", + " for iq_list in prog.get_rounds():\n", + " for ii, iq in enumerate(iq_list):\n", + " t = 1000 * prog.get_time_axis(ro_index=ii)\n", + " axes[i].plot(t, get_inphase(iq.T), \n", + " label=f\"ADC {config['ro_chs'][ii]}\", \n", + " color=colors[ii], alpha=0.7)\n", + " axes[i].set_ylabel(\"Amplitude (a.u.)\")\n", + " axes[i].set_xlabel(\"Time (ns)\")\n", + " axes[i].legend()\n", + " axes[i].grid(True)\n", + " \n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.3 Jitter Analysis\n", + "\n", + "Calculate the pulse edge positions and analyze the inter-board jitter." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Fit pulse edges for all rounds\n", + "edges = np.array([[\n", + " [find_edges(get_inphase(iq.T)) for iq in iq_list] \n", + " for iq_list in prog.get_rounds()\n", + "] for prog in progs])\n", + "\n", + "# Convert to ns\n", + "edges *= progs[0].get_time_axis(ro_index=0)[1] * 1e3\n", + "\n", + "# Use the average of rising and falling edges as the pulse time\n", + "pulsetimes = edges[..., :2].mean(axis=-1)\n", + "\n", + "# Plot jitter correlations\n", + "fig, axes = plt.subplots(2, 2, figsize=(10, 10))\n", + "\n", + "# Cross-correlation between readouts on same board\n", + "for i_soc in range(len(proxies)):\n", + " plot_jitter(axes[0, i_soc], \n", + " pulsetimes[i_soc, :, 0], \n", + " pulsetimes[i_soc, :, 1])\n", + " axes[0, i_soc].set_xlabel(f\"ADC {0}, Board {i_soc} (ns)\")\n", + " axes[0, i_soc].set_ylabel(f\"ADC {1}, Board {i_soc} (ns)\")\n", + " axes[0, i_soc].set_title(f\"Board {i_soc} - Intra-Board Jitter\")\n", + "\n", + "# Cross-correlation between boards for same readout\n", + "for i_ro in range(len(RO_CHS)):\n", + " plot_jitter(axes[1, i_ro],\n", + " pulsetimes[0, :, i_ro],\n", + " pulsetimes[1, :, i_ro])\n", + " axes[1, i_ro].set_xlabel(f\"ADC {i_ro}, Board 0 (ns)\")\n", + " axes[1, i_ro].set_ylabel(f\"ADC {i_ro}, Board 1 (ns)\")\n", + " axes[1, i_ro].set_title(f\"ADC {i_ro} - Inter-Board Jitter\")\n", + "\n", + "plt.tight_layout()\n", + "plt.show()\n", + "\n", + "# Print jitter statistics\n", + "print(\"\\n=== Jitter Analysis ===\")\n", + "for i_ro in range(len(RO_CHS)):\n", + " diff = pulsetimes[0, :, i_ro] - pulsetimes[1, :, i_ro]\n", + " print(f\"ADC {i_ro} inter-board jitter: {np.std(diff):.3f} ns RMS\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. tProc v2 Example\n", + "\n", + "The same approach works with tProc v2, but you need firmware revision 24 or later.\n", + "\n", + "**Important:** For jitter-free operation, the tProc dispatcher clock should be an integer multiple of the core clock. Standard firmwares have been updated to meet this requirement.\n", + "\n", + "**Recommended firmwares:**\n", + "- ZCU111: https://s3df.slac.stanford.edu/people/meeg/qick/tprocv2/2025-06-05_111_tprocv2r24_standard/\n", + "- ZCU216: https://s3df.slac.stanford.edu/people/meeg/qick/tprocv2/2025-06-15_216_tprocv2r24_standard/\n", + "- RFSoC4x2: https://s3df.slac.stanford.edu/people/meeg/qick/tprocv2/2025-06-15_4x2_tprocv2r24_standard/" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Channel configuration for tProc v2\n", + "GEN_CHS = [7, 6]\n", + "RO_CHS = [0, 1]\n", + "TRIG_TIME = 0.35 # us\n", + "FREQ = 500 # MHz\n", + "\n", + "print(f\"Generator channels: {GEN_CHS}\")\n", + "print(f\"Readout channels: {RO_CHS}\")\n", + "print(f\"Frequency: {FREQ} MHz\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class LoopbackProgramV2(AveragerProgramV2):\n", + " \"\"\"\n", + " Loopback program for tProc v2.\n", + " Generates a pulse and measures it on the same board or across boards.\n", + " \"\"\"\n", + " def _initialize(self, cfg):\n", + " ro_chs = cfg['ro_chs']\n", + " gen_chs = cfg['gen_chs']\n", + " for gen_ch in gen_chs:\n", + " self.declare_gen(ch=gen_ch, nqz=1)\n", + " # Create a custom envelope with ramps\n", + " maxv = self.get_maxv(gen_ch)\n", + " idata = np.ones(10*16, dtype=np.int32) * maxv\n", + " idata[:cfg['ramp_nsamp']] = np.linspace(0, maxv, cfg['ramp_nsamp'], dtype=np.int32)\n", + " idata[:-cfg['ramp_nsamp']-1:-1] = np.linspace(0, maxv, cfg['ramp_nsamp'], dtype=np.int32)\n", + " qdata = np.zeros(10*16, dtype=np.int32)\n", + " self.add_envelope(ch=gen_ch, name=\"ramp\", idata=idata, qdata=qdata)\n", + "\n", + " self.add_pulse(ch=gen_chs,\n", + " name=\"mypulse\",\n", + " ro_ch=ro_chs[0],\n", + " style=\"flat_top\",\n", + " envelope=\"ramp\",\n", + " freq=cfg['freq'],\n", + " length=cfg['pulse_len'],\n", + " phase=cfg['gen_phase'],\n", + " gain=cfg['gen_gain'])\n", + "\n", + " for ro_ch in ro_chs:\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'])\n", + "\n", + " self.add_readoutconfig(ch=ro_chs,\n", + " name=\"myro\",\n", + " freq=cfg['freq'],\n", + " gen_ch=gen_chs[0])\n", + "\n", + " for ro_ch in ro_chs:\n", + " self.send_readoutconfig(ch=ro_ch, name=\"myro\", t=0)\n", + " \n", + " if cfg['send_start']:\n", + " self.delay(0.5) # give processor some time to set registers\n", + " self.trigger(pins=[0], t=0) # output a pulse on PMOD0_0, to trigger the follower\n", + " self.delay(cfg['leader_delay']) # give follower time to catch up\n", + " if cfg['follower_delay'] > 0:\n", + " self.delay(cfg['follower_delay'])\n", + " \n", + " def _body(self, cfg):\n", + " self.delay(10)\n", + " for gen_ch in cfg['gen_chs']:\n", + " self.pulse(ch=gen_ch, name=\"mypulse\", t=0)\n", + " self.trigger(ros=cfg['ro_chs'], t=cfg['trig_time'])\n", + "\n", + "# Base configuration for tProc v2\n", + "config = {\n", + " 'gen_chs': GEN_CHS,\n", + " 'ro_chs': RO_CHS,\n", + " 'freq': FREQ,\n", + " 'trig_time': TRIG_TIME,\n", + " 'ro_len': 0.2,\n", + " 'pulse_len': 0.05,\n", + " 'ramp_nsamp': 32, # DAC samples\n", + " 'gen_gain': 1.0,\n", + " 'gen_phase': 0.0,\n", + " 'send_start': False,\n", + " 'leader_delay': 0.05, # us\n", + " 'follower_delay': 0, # us\n", + "}\n", + "\n", + "print(\"tProc v2 loopback program defined.\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Test each board individually with tProc v2\n", + "progs = []\n", + "config['send_start'] = False\n", + "\n", + "for i, (soc, soccfg) in enumerate(proxies):\n", + " progs.append(LoopbackProgramV2(soccfg, reps=1, final_delay=0.5, cfg=config))\n", + " \n", + "iq_lists = []\n", + "for i, (soc, soccfg) in enumerate(proxies):\n", + " print(f\"Acquiring data from board {i+1} (tProc v2)...\")\n", + " iq_lists.append(progs[i].acquire_decimated(soc, progress=True, rounds=100))\n", + "\n", + "# Plot results\n", + "fig, axes = plt.subplots(len(iq_lists), 1, figsize=(15, 8))\n", + "if len(iq_lists) == 1:\n", + " axes = [axes]\n", + " \n", + "for i, iq_list in enumerate(iq_lists):\n", + " axes[i].set_title(f\"Board {i+1} (tProc v2)\")\n", + " for ii, iq in enumerate(iq_list):\n", + " axes[i].plot(iq[:, 0], label=f\"I, ADC {config['ro_chs'][ii]}\", alpha=0.7)\n", + " axes[i].plot(iq[:, 1], label=f\"Q, ADC {config['ro_chs'][ii]}\", alpha=0.7)\n", + " axes[i].plot(np.abs(iq.dot([1, 1j])), label=f\"Mag, ADC {config['ro_chs'][ii]}\", alpha=0.7)\n", + " axes[i].set_ylabel(\"Amplitude (a.u.)\")\n", + " axes[i].set_xlabel(\"Sample\")\n", + " axes[i].legend()\n", + " axes[i].grid(True)\n", + " \n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Synchronized acquisition with tProc v2\n", + "# Adjust leader_delay for alignment (use cycles2us conversion)\n", + "config['leader_delay'] = soccfg.cycles2us(22) # Convert tProc cycles to us\n", + "\n", + "progs = []\n", + "for i, (soc, soccfg) in enumerate(proxies):\n", + " config['send_start'] = (i == 0) # Only leader sends start pulse\n", + " progs.append(LoopbackProgramV2(soccfg, reps=1, final_delay=0.5, cfg=config))\n", + "\n", + "# Run synchronized acquisition\n", + "loop = asyncio.get_event_loop()\n", + "iq_lists = loop.run_until_complete(\n", + " run_multi_decimated(loop, proxies, progs, rounds=100)\n", + ")\n", + "\n", + "# Plot results\n", + "fig, axes = plt.subplots(len(progs), 1, figsize=(15, 10))\n", + "if len(progs) == 1:\n", + " axes = [axes]\n", + " \n", + "colors = ['blue', 'red']\n", + "for i, prog in enumerate(progs):\n", + " axes[i].set_title(['Leader', 'Follower'][i])\n", + " for iq_list in prog.get_rounds():\n", + " for ii, iq in enumerate(iq_list):\n", + " t = 1000 * prog.get_time_axis(ro_index=ii)\n", + " axes[i].plot(t, get_inphase(iq), \n", + " label=f\"ADC {config['ro_chs'][ii]}\", \n", + " color=colors[ii], alpha=0.7)\n", + " axes[i].set_ylabel(\"Amplitude (a.u.)\")\n", + " axes[i].set_xlabel(\"Time (ns)\")\n", + " axes[i].legend()\n", + " axes[i].grid(True)\n", + " \n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Jitter analysis for tProc v2\n", + "edges = np.array([[\n", + " [find_edges(get_inphase(iq)) for iq in iq_list] \n", + " for iq_list in prog.get_rounds()\n", + "] for prog in progs])\n", + "\n", + "# Convert to ns\n", + "edges *= progs[0].get_time_axis(ro_index=0)[1] * 1e3\n", + "\n", + "# Pulse times from average of rising and falling edges\n", + "pulsetimes = edges[..., :2].mean(axis=-1)\n", + "\n", + "# Plot jitter correlations\n", + "fig, axes = plt.subplots(2, 2, figsize=(10, 10))\n", + "\n", + "for i_soc in range(len(proxies)):\n", + " plot_jitter(axes[0, i_soc], \n", + " pulsetimes[i_soc, :, 0], \n", + " pulsetimes[i_soc, :, 1])\n", + " axes[0, i_soc].set_xlabel(f\"ADC {0}, Board {i_soc} (ns)\")\n", + " axes[0, i_soc].set_ylabel(f\"ADC {1}, Board {i_soc} (ns)\")\n", + " axes[0, i_soc].set_title(f\"Board {i_soc} (tProc v2) - Intra-Board Jitter\")\n", + "\n", + "for i_ro in range(len(RO_CHS)):\n", + " plot_jitter(axes[1, i_ro],\n", + " pulsetimes[0, :, i_ro],\n", + " pulsetimes[1, :, i_ro])\n", + " axes[1, i_ro].set_xlabel(f\"ADC {i_ro}, Board 0 (ns)\")\n", + " axes[1, i_ro].set_ylabel(f\"ADC {i_ro}, Board 1 (ns)\")\n", + " axes[1, i_ro].set_title(f\"ADC {i_ro} (tProc v2) - Inter-Board Jitter\")\n", + "\n", + "plt.tight_layout()\n", + "plt.show()\n", + "\n", + "# Print jitter statistics\n", + "print(\"\\n=== Jitter Analysis (tProc v2) ===\")\n", + "for i_ro in range(len(RO_CHS)):\n", + " diff = pulsetimes[0, :, i_ro] - pulsetimes[1, :, i_ro]\n", + " print(f\"ADC {i_ro} inter-board jitter: {np.std(diff):.3f} ns RMS\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Summary\n", + "\n", + "You have learned:\n", + "\n", + "1. **External Clock Synchronization**: Locking multiple boards to a common reference clock\n", + "2. **External Start Signaling**: Using PMOD pins to synchronize tProc start\n", + "3. **Leader-Follower Architecture**: One board triggers others via external start\n", + "4. **Software Synchronization**: Coordinating multiple programs with async/await\n", + "5. **Jitter Measurement**: Quantifying inter-board timing accuracy\n", + "\n", + "### Key Takeaways\n", + "\n", + "- tProc v1 external start works reliably; tProc v2 requires revision 24+\n", + "- The phase relationship between tProc clocks is random; re-initialize if you see one-tick jitter\n", + "- For multi-follower setups, wire all followers' external start pins to the leader's output\n", + "- The jitter is typically below the measurement resolution of this technique (limited by decimated data interpolation)\n", + "- For better jitter measurements, use a scope or the time-tagger readout\n", + "\n", + "### Next Steps\n", + "\n", + "- Proceed to [`11_Streaming_And_RealTime_Processing.ipynb`](./11_Streaming_And_RealTime_Processing.ipynb)\n", + "- For more advanced multi-board synchronization, see the XCOM network documentation" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "hvenv (3.12.3)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/source/tutorials/11_Streaming_And_RealTime_Processing.ipynb b/docs/source/tutorials/11_Streaming_And_RealTime_Processing.ipynb new file mode 100644 index 000000000..3ebf9ab0a --- /dev/null +++ b/docs/source/tutorials/11_Streaming_And_RealTime_Processing.ipynb @@ -0,0 +1,2117 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 11 - Streaming and Real-Time Processing\n", + "\n", + "**Objective:** Implement IQ streaming, on-FPGA averaging, and real-time decimation. This notebook covers:\n", + "- Streaming mode for continuous IQ data capture\n", + "- On-FPGA averaging for noise reduction\n", + "- Real-time decimation to reduce data bandwidth\n", + "- Comparison of streaming vs. buffered readout modes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%pybind11/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ready\n" + ] + } + ], + "source": [ + "# Standard imports\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import logging\n", + "from scipy import signal\n", + "\n", + "from qick import *\n", + "from qick.asm_v2 import AveragerProgramV2\n", + "\n", + "# Setup logging\n", + "logging.basicConfig(level=logging.INFO, format='%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s')\n", + "\n", + "# Connect to the board\n", + "BITSTREAM_PATH = 'qick_216.bit'#'/path/to/your/firmware.bit' # <--- CHANGE THIS\n", + "soc = QickSoc(BITSTREAM_PATH)\n", + "soccfg = soc\n", + "\n", + "# Define hardware channels\n", + "GEN_CH = 0\n", + "RO_CH = 0\n", + "\n", + "print(\"Ready\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Streaming Mode Overview\n", + "\n", + "By default, the QICK captures readout data in **buffered mode**, where data is stored in on-board memory and transferred after the experiment. \n", + "\n", + "**Streaming mode** continuously streams IQ data from the ADC to the host computer in real-time. This is useful for:\n", + "- Monitoring signals over long periods\n", + "- Real-time feedback and decision making\n", + "- Capturing transient events\n", + "- High-throughput experiments\n", + "\n", + "The trade-off: streaming generates large amounts of data and requires high-bandwidth communication." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Basic Streaming Example\n", + "\n", + "Let's configure a simple streaming acquisition." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "fb3621f62eff4705bfa84172ddebef71", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/1 [00:00" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total samples captured: 307\n" + ] + } + ], + "source": [ + "class StreamingProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['pulse_len'])\n", + " \n", + " self.add_pulse(\n", + " ch=cfg['gen_ch'], name=\"test_pulse\",\n", + " style=\"const\",\n", + " freq=cfg['freq'], length=cfg['pulse_len'],\n", + " phase=0, gain=cfg['gain']\n", + " )\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"ro\",\n", + " freq=cfg['freq'], gen_ch=cfg['gen_ch'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"ro\", t=0)\n", + "\n", + " def _body(self, cfg):\n", + " self.pulse(ch=cfg['gen_ch'], name=\"test_pulse\", t=0)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=0.035)\n", + "\n", + "config_stream = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500.0,\n", + " 'pulse_len': 1.0,\n", + " 'gain': 0.5,\n", + "}\n", + "\n", + "prog = StreamingProgram(soccfg, reps=1, final_delay=0.5, cfg=config_stream)\n", + "\n", + "# acquire_decimated returns the IQ samples over time.\n", + "iq_list = prog.acquire_decimated(soc, rounds=1)\n", + "# iq_list[ro_ch] tiene shape (samples, 2) -> columna 0=I, columna 1=Q\n", + "i_data = iq_list[0][:, 0]\n", + "q_data = iq_list[0][:, 1]\n", + "\n", + "plt.figure(figsize=(12, 5))\n", + "plt.subplot(1, 2, 1)\n", + "plt.plot(i_data, label='I')\n", + "plt.plot(q_data, label='Q')\n", + "plt.xlabel('Sample Index')\n", + "plt.ylabel('Amplitude (ADC counts)')\n", + "plt.title('Raw IQ Data')\n", + "plt.legend()\n", + "plt.grid(True)\n", + "\n", + "plt.subplot(1, 2, 2)\n", + "plt.plot(i_data, q_data, '.')\n", + "plt.xlabel('I')\n", + "plt.ylabel('Q')\n", + "plt.title('IQ Constellation')\n", + "plt.axis('equal')\n", + "plt.grid(True)\n", + "\n", + "plt.tight_layout()\n", + "plt.show()\n", + "\n", + "print(f\"Total samples captured: {len(i_data)}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Decimation in Streaming Mode\n", + "\n", + "Decimation reduces the data rate by averaging or downsampling. This is crucial for long experiments where you don't need the full sample rate." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n" + ] + }, + { + "data": { + "image/png": "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uxFjZWVwY7fDDz+cZ5999oDfw7Rp03j55ZcPeH0RkREJC6y6stjkvYKlPDWoZ599lnXr1vHNb36TjRs37jM/W3lKBZaIjEyYsOKk2NbcObkLrBxYunQpv/jFL/aa1tLSwo4dOzj88MP3ml5SUkJX194du4dKeueeey4/+clP9pr+/PPPD7r8wV7B6urqoqREvzciMsYsaGExtTTKa5O1wMqBQshTjz76KE899RTz588nlUqxc+dO3vrWt/LQQw8B2ctTauMjIiPT7wrWtmaNyjTezj77bDo6OvjRj34EQDqd5lOf+hTXXHPNPslg8eLFe52ZO/3007nlllsAePHFF3n++eeBoL/UI488wrp16wDo6Ohg7dq1HHHEEWzdupUnnngCgNbWVlKpVN+ZwcEe+yuuANauXbvXiE0iImMiPCE4tSzKrjYVWONlsDx17bXX5lWe+vCHP8zWrVvZuHEjDz/8MIsXL+buu/fc5SlbeUoFloiMTNgHK06KbU0qsMabmXHHHXfw85//nMMOO4z58+cTiUS49tpr91m2rKyMRYsW9SWkD3/4w7S1tXH00Ufz9a9/va9teV1dHTfffDPvec97OProoznllFN4+eWXSSQS3H777Xz0ox/lmGOO4dxzz93nTONQPv3pTzNnzhw6Ojo44ogj+OIXv9g375FHHuGcc845+IMhIjKccJCL2tLo5G0imAMD81RtbW1e5qnhZCtPqYmgiIxMWGCVxjLsaFGBlQtz587lrrvuAuC+++7jAx/4AE899dQ+nYoBrrnmGm6++Wa+/OUvU1JSwm233TboNs8666y+M4D9nXjiiTz22GOjjvHrX/86X//614HgjGLviE7PPPMMS5cuZerUqaPepojIqIRXsGpLonT0pGnvTlFWpH95x0P/PPWnP/2Jyy67LO/yVK/58+fz4osv0traCmQ3T+m3TURGJhIUWDXFxhY1uci5k08+mddee23I+ZdccgkNDQ3jGNHw6uvr+Zd/+ZdchyEik0FYYNWURgFnV2u3CqwceMMb3sCqVauGHDp9Iucp/baJyMiEfbCqi4xnWiZngTXUCEn56q//+q9zHUKfc889d9Dpg40uJSJyUMJBLmqKI0CaXW3dzJ9altuYxony1IEbKk/B6HOV+mCJyMhEg/MxU4p8UnYaLi4upqGhQQVBFrk7DQ0NFBcX5zoUEZlI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eEREhtSyDZLt0LY915FMePmWq9yda6+9lsWLF3PkkUdy3XXX7TX/iSeeIBqN9u1/rHOVCiwRGZnWbdC5e1I0vchHN910E5deeinRaHRc93vaaadx3333MW/evL2mNzU18ZGPfIS77rqLVatW8bOf/QyARCLB2Wefze233z6ucYqI0LYj+JlO5jaOSSxXuermm29m06ZNvPzyy6xevZrLLrusb146neYf/uEfeMtb3tI3baxzlQosEdk/9zBxOc++spHmDiWv8XbLLbdw0UUXAcGZuk996lMsWbKECy64gJ07d/Yt99RTT3HGGWdwwgkn8Ja3vIVt27YBsG7dOs455xyOOeYYjj/+eNavXz+i/R533HHMnz9/n+m33norl156KYcccggA06ZN65t38cUXc8sttxzoWxUROTB9BVZPbuOYxHKVq2644QY+//nPE4kEpU3/nPRf//VfvOMd79hrGoxtrpoww7Sb2XnAt4Ao8D13/7cchyQycXS3QLIDgE/98A9cfPaZfPTsw3Ic1Nj651+v4qWtLVnd5pJZlXzhwqWjXq+np4cNGzb0FTp33HEH69at44UXXmDHjh0sWbKEq666imQyyUc/+lHuvPNO6urquP3227n22mu56aabeN/73sdnPvMZLrnkErq6ushkMrS2tvKmN71p0H3eeuutLFmyZMiY1q5dSzKZZMWKFbS2tvLxj3+cyy+/HIBly5bxxBNPjPp9iogclLbwH/hJVGApVwW5av369dx+++3ccccd1NXVcd1113HYYYexZcsW7rjjDu6///598tJY5qoJUWCZWRT4b+BcYDPwhJnd5e4v5TYykcLWlUxTFItgrTv6pk3xVrY2a1jt8VRfX091dXXf6wcffJB3vvOdRKNRZs2axVlnnQXAmjVrePHFFzn33HOBoFnEzJkzaW1tZcuWLVxyySVAcMPEXs8+++wBxZRKpXjqqaf4wx/+QGdnJ6eeeiqnnHIKixcvJhqNkkgkCuL+JyIygfRdwVIf0FzIZa7q7u6muLiYJ598kl/+8pdcddVVPPTQQ3ziE5/ga1/72qBNFscyV02IAgs4CVjn7hsAzOw24CJgTAqs5sZdJF7+Oa/PrqFs5uE4sLutm+b6rcQ7tuGROB1VhzKlvJRZ1SVUxdJgEYglcHfae9KURdNYdxuYkYpX0JmG8qIYuLN7dwPbumJk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\n", + "text/plain": [ + "
      " + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Decimation Summary:\n", + " dec=1: 614 samples\n", + " dec=4: 614 samples\n", + " dec=16: 614 samples\n", + " dec=64: 614 samples\n" + ] + } + ], + "source": [ + "decimations = [1, 4, 16, 64]\n", + "results = {}\n", + "\n", + "for dec in decimations:\n", + " config = config_stream.copy()\n", + " config['pulse_len'] = 2.0\n", + "\n", + " prog = StreamingProgram(soccfg, reps=1, final_delay=0.5, cfg=config)\n", + " iq_list = prog.acquire_decimated(soc, rounds=1, progress=False)\n", + " results[dec] = {\n", + " 'i': iq_list[0][:, 0],\n", + " 'q': iq_list[0][:, 1],\n", + " }\n", + "\n", + "plt.figure(figsize=(12, 8))\n", + "for idx, dec in enumerate(decimations):\n", + " plt.subplot(2, 2, idx+1)\n", + " data = results[dec]\n", + " samples_to_plot = min(200, len(data['i']))\n", + " plt.plot(data['i'][:samples_to_plot], label=f'I (dec={dec})')\n", + " plt.plot(data['q'][:samples_to_plot], label=f'Q (dec={dec})')\n", + " plt.xlabel('Sample Index')\n", + " plt.ylabel('Amplitude')\n", + " plt.title(f'Decimation Factor: {dec}\\n({len(data[\"i\"])} total samples)')\n", + " plt.legend()\n", + " plt.grid(True)\n", + "\n", + "plt.tight_layout()\n", + "plt.show()\n", + "\n", + "print(\"Decimation Summary:\")\n", + "for dec in decimations:\n", + " print(f\" dec={dec}: {len(results[dec]['i'])} samples\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Real-Time Averaging\n", + "\n", + "The QICK FPGA can perform on-the-fly averaging of multiple shots. This reduces noise without transferring all raw data to the host." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "iq_avg[0] shape: (6, 154, 2)\n", + "time_axis shape: (154,)\n", + "reps_per_round: 6\n", + "n_rounds: 16\n", + "f_output: 307.2 MHz\n", + "buf_maxlen: 1024\n", + "samples_per_rep: 153\n" + ] + } + ], + "source": [ + "print(\"iq_avg[0] shape:\", iq_avg[0].shape)\n", + "print(\"time_axis shape:\", time_axis.shape)\n", + "print(\"reps_per_round:\", reps_per_round)\n", + "print(\"n_rounds:\", n_rounds)\n", + "print(\"f_output:\", soccfg['readouts'][RO_CH]['f_output'], \"MHz\")\n", + "print(\"buf_maxlen:\", buf_maxlen)\n", + "print(\"samples_per_rep:\", samples_per_rep)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Raw ADC rate: 2457.6 MHz\n", + "Decimated rate: 307.2 MHz\n", + "ro_len: 2.0 µs\n", + "Samples per rep: 614\n", + "Buffer max: 1024 samples\n", + "Max reps: 1\n", + "Using reps=1, rounds=100\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "iq_avg type: \n", + "iq_avg length: 1\n", + "iq_avg[0] shape: (614, 2)\n", + "data_avg shape: (614, 2)\n" + ] + }, + { + "data": { + "image/png": "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/d+A9XHP0NOAw1t8dpFmUJs1EWmOdevW8cILL3DHHXfkg7XHHnuMc845J79NVVUVZ5wRTdLz+OOPc8wxxzB8+HC+9a1vsW7dOgAGDBjAf/zHf3D88cfzwAMPcPvttzNy5EiGDh3K2Wefnf8yfv/99xk1ahQjR47k2muv3aa05uc//zkjR45kyJAh25S2TJw4kYMPPpgvfelLvPvuuw3m48ILL2TcuHGcdNJJDBo0iL/+9a9cdNFFfP7zn+fCCy/Mbzdu3DhGjBjB4MGDtznHo48+yiGHHMLxxx/PD3/4Q04//XQgKsm76KKLqKysZNCgQUyaNCm/Ty7t48eP57nnnmPYsGHccsst25WYnX766VRVVQHw29/+loMOOogvfOELvPDC1tG9PvnkE84++2xGjhzJyJEjt1mXU11dzVtvvcXQoUMB6N27NyNHjtyux+Qrr7zCAQccwKBBg+jUqRNjxozhoYceAuChhx5i7NixAIwdO5YHH3xwu/MsW7aME088kWHDhnHYYYfx3HPP5df9+Mc/ZujQoYwaNYrly5cDsGjRIk4++WSGDBnCGWecweLFi3nxxReZPn06V111FcOGDeP9999n0qRJHHrooQwZMoQxY8YAUXVnZWUlDz/8cEO3tVmK7Q1aE/9ebWaHAR8DA1p8dpFmiGYwULQmkjb//qdZzP5o7U7tu6U2S202yy6dtv26OnTvXbnujME73PfBBx9k9OjRHHTQQfTs2ZOZM2dyyimn8P3vf5/169fTrVs37rvvPs4991w+/fRTrr/+ep588km6devGT3/6U2666SauvfZaIBpu4fnnn6e6upotW7ZwySWXAHDNNddwxx138IMf/IArrriCK664gvPOO49f//rX+XQ8/vjjzJs3j1deeQV358wzz+TZZ5+lW7duTJs2jddff53a2lqGDx/OkUce2WBeVq1axdNPP8306dM544wzeOGFF/jNb37DyJEjeeONNxg2bBgTJ06kZ8+e1NXVcfLJJ/PWW29x0EEH8f3vf59nn32WgQMHct55521z3Llz5/LMM89QXV3NwQcfzLhx47YJkG644QZuvPFGHn74Yaqrq/nDH/7QYPqWLVvGddddx4wZM9htt9046aSTOOKIIwC44ooruPLKKzn++ONZvHgxp5566nZDYLz22mscdljTEyN9+OGH9O/fP/++X79+vPzyywAsX76cvn37AtC3b19WrFix3f733nsvp556Kj/+8Y+pq6vLB9rr169n1KhRTJw4kR/96EfcfvvtXHPNNVx++eVccMEFjB07lltvvZUf/vCHPPjgg5x55pmcfvrpfPOb38xfpwULFtC5c2dWr16dP9+IESN47rnntvkHYWcUW7J2m5ntAVwDTAdmAz9t0ZlFmsnRJO4iUrypU6fmSznGjBnD1KlTKS8vZ/To0fzpT3+itraWRx55hLPOOou//e1vzJ49m+OOO45hw4YxZcoUFi1alD/Wueeem3/9zjvvcMIJJ3D44Ydzzz33MGvWLABeeuklvvWtbwHw7W9/O7/9448/zuOPP84RRxzB8OHDmTt3LvPmzeO5557j61//Orvssgu77rorZ555ZqN5OeOMMzAzDj/8cPr06cPhhx9OJpNh8ODBLFy4EID777+f4cOHc8QRRzBr1ixmz57N3LlzGTRoUH6YiPrB2mmnnUbnzp3p1asXvXv3zpcoNdfLL79MZWUle+21F506ddrmej355JNcfvnlDBs2jDPPPJO1a9dSXb1tS6ply5ax1157NXmehuaJbc4/8SNHjuS3v/0tEyZM4O23384PxdGpU6d8ieORRx6Zv6YvvfRS/l6OGTOG559/vsHjDhkyhO985zvcfffdlJdv/ceid+/efPTRR0WnrzHFDor7m/jls8CgFp9VZCdkVbImkkpNlYDtyEerN7JqwxYG771bs/ZbuXIlTz/9NO+88w5mRl1dHWbGz372M84991x+9atf0bNnT0aOHEmPHj1wd0455RSmTp3a4PG6deuWf33hhRfy4IMPMnToUCZPnpyvBmyMu3P11Vfz/e9/f5vlN998c9F/0zp37gxAJpPJv869r62tZcGCBdx44428+uqr7LHHHlx44YVs2rSpweCmoeMClJWVUVtbu8Pty8vLyRZMKVE4BEVjeclms7z00kt07dq10eN27dq1qOEs+vXrx5IlS/Lvly5dyt577w1Anz59WLZsGX379mXZsmX07t17u/1PPPFEnn32WR555BHOP/98rrrqKi644AIqKiry6d/RdWgsj4888gjPPvss06dP5yc/+QmzZs2ivLycTZs27TDfxdphyZqZfdfMGt3GzPY3s+NbnAqRIkRzgyadChEpuZ3oDfr73/+eCy64gEWLFrFw4UKWLFnCwIEDef75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\n", + "text/plain": [ + "
      " + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Data shape after averaging: (614, 2)\n", + "Mean magnitude: 506.9764\n", + "Peak magnitude: 1037.8815\n", + "Time range: 0.000 – 1.995 µs\n" + ] + } + ], + "source": [ + "class AveragingProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + " \n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"test_pulse\",\n", + " style=\"const\",\n", + " freq=cfg['freq'], length=cfg['pulse_len'],\n", + " phase=0, gain=cfg['gain'])\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\",\n", + " freq=cfg['freq'], gen_ch=cfg['gen_ch'])\n", + "\n", + " def _body(self, cfg):\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", t=0) # move here\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'])\n", + " self.pulse(ch=cfg['gen_ch'], name=\"test_pulse\", t=0)\n", + " \n", + "config_avg = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500.0,\n", + " 'pulse_len': 1.0, # longer pulse so it fills the readout window\n", + " 'gain': 0.5,\n", + " 'trig_time': 0.05, # keep small — trigger early, capture the turn-on transient\n", + " 'ro_len': 2.0, # longer window to see full pulse + ringdown\n", + " 'avg_rounds': 100\n", + "}\n", + "\n", + "# Calculate the maximum number of reps that fit in the buffer.\n", + "buf_maxlen = soccfg['readouts'][RO_CH]['buf_maxlen']\n", + "\n", + "# Use f_output (decimated rate), not fs (raw ADC rate)\n", + "f_output = soccfg['readouts'][RO_CH]['f_output'] # MHz, after decimation\n", + "samples_per_rep = int(config_avg['ro_len'] * f_output)\n", + "\n", + "print(f\"Raw ADC rate: {soccfg['readouts'][RO_CH]['fs']} MHz\")\n", + "print(f\"Decimated rate: {f_output} MHz\")\n", + "print(f\"ro_len: {config_avg['ro_len']} µs\")\n", + "print(f\"Samples per rep: {samples_per_rep}\")\n", + "print(f\"Buffer max: {buf_maxlen} samples\")\n", + "\n", + "max_reps = buf_maxlen // max(samples_per_rep, 1) # guard against zero\n", + "print(f\"Max reps: {max_reps}\")\n", + "\n", + "# Clamp reps to buffer limit, then compute rounds to hit avg_rounds total\n", + "reps_per_round = max(1, min(config_avg['avg_rounds'], max_reps))\n", + "n_rounds = max(1, config_avg['avg_rounds'] // reps_per_round)\n", + "print(f\"Using reps={reps_per_round}, rounds={n_rounds}\")\n", + "\n", + "prog = AveragingProgram(soccfg, reps=reps_per_round, final_delay=0.5, cfg=config_avg)\n", + "iq_avg = prog.acquire_decimated(soc, rounds=n_rounds, progress=False)\n", + "\n", + "print(\"iq_avg type:\", type(iq_avg))\n", + "print(\"iq_avg length:\", len(iq_avg))\n", + "print(\"iq_avg[0] shape:\", np.array(iq_avg[0]).shape)\n", + "\n", + "# acquire_decimated returns list of arrays, one per ro_ch\n", + "# shape is typically (reps, n_samples, 2) — need to average over reps first\n", + "data = np.array(iq_avg[0])\n", + "\n", + "if data.ndim == 3:\n", + " # (reps, n_samples, 2) → average over reps\n", + " data_avg = data.mean(axis=0) # (n_samples, 2)\n", + "elif data.ndim == 2 and data.shape[-1] == 2:\n", + " # already (n_samples, 2) — no averaging needed\n", + " data_avg = data\n", + "elif data.ndim == 2 and data.shape[-1] != 2:\n", + " # (reps, 2) — single sample per rep, not time-resolved\n", + " data_avg = data.mean(axis=0, keepdims=True) # (1, 2)\n", + "else:\n", + " raise ValueError(f\"Unexpected data shape: {data.shape}\")\n", + "\n", + "print(\"data_avg shape:\", data_avg.shape)\n", + "\n", + "magnitude = np.abs(data_avg[:, 0] + 1j * data_avg[:, 1])\n", + "time_axis = prog.get_time_axis(ro_index=0)\n", + "\n", + "# Trim to matching length if needed\n", + "n = min(len(time_axis), len(magnitude))\n", + "plt.figure(figsize=(10, 5))\n", + "plt.plot(time_axis[:n], magnitude[:n],\n", + " label=f'Averaged magnitude ({reps_per_round * n_rounds} shots)')\n", + "plt.xlabel('Time (µs)')\n", + "plt.ylabel('|IQ| (a.u.)')\n", + "plt.title(f'Averaging: {reps_per_round} reps × {n_rounds} rounds = {reps_per_round * n_rounds} total')\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.show()\n", + "\n", + "print(f\"Data shape after averaging: {data_avg.shape}\")\n", + "print(f\"Mean magnitude: {magnitude.mean():.4f}\")\n", + "print(f\"Peak magnitude: {magnitude.max():.4f}\")\n", + "print(f\"Time range: {time_axis[0]:.3f} – {time_axis[-1]:.3f} µs\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. Streaming vs. Buffered Readout Comparison\n", + "\n", + "Understanding the difference between streaming and buffered modes helps you choose the right approach for your experiment." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "f_output: 307.2 MHz\n", + "Buffer: 1024, samples/rep: 184, max_reps: 5\n", + "Single shape: (184, 2), Avg shape: (184, 2)\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+gAAAFgCAYAAAAo31N4AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAABozUlEQVR4nO3deZhcZ3nn/e99au1dUktq7YtteZFkY1vygoFYxoDNamCAmCUmQOJAIECGDIF43oTMjCfLJCEQAomHJMQJDDgEYwNesOM0qxds402SbcmWLbcWa+t9qfV+/zinu0tSq9WSu7q6qn6f66qrq06d5a6nW3rqPs9m7o6IiIiIiIiIVFZQ6QBERERERERERAm6iIiIiIiIyKygBF1ERERERERkFlCCLiIiIiIiIjILKEEXERERERERmQWUoIuIiIiIiIjMAkrQRSrMzN5rZj+cpnN1mtlvTMe5ynnOI86fMrMtZraoXNcoJzN7wMzWVToOERGRl8rMVpmZm1l8kn3+xMw+OYNhTRsz+7iZ/Wml4xCZjBJ0kRlgZq80s5+bWa+ZHTKzn5nZBQDu/nV3f12lYywHM3vOzF5znN2uBX7s7ntnIqYTZWbrzexOMztgZj7BLn8B/I+ZjktERGaH6EZ2t5mlKh1LuZnZAuAa4O8rHcuxRDcYBs1sIHp8teTtG4D3mdnCSsUncjxK0EXKzMxage8DfwPMA5YCfwxkKhnXLPJbwL8c600zi81gLBPJATcBHzrG+7cCl5nZ4pkLSUREZgMzWwW8CnDgLWU4/zFbsivk14Hb3H14ojdnUbwvc/fm6DHWC9DdR4DbCW8yiMxKStBFyu90AHf/f+5ecPdhd/+huz8GYGa/bmY/Hd05uvP7YTPbFt2R/1szs+i9mJn9ZdSau8PMPjZZVzQz+6CZbY3Oc6eZrTzGfmkz+1czO2hmPWb2CzPrKNllZdTq329mPzSz+SXHvsXMNkfHdZrZWdH2fwFWAN+L7mB/eoLrrgBOBe4v2fY1M/uKmd1mZoOEye8SM/t3M9sffe6Pl+z/OTP7tpl9K4rvYTN7Wcn7v29mu6L3njKzyyf7ZR3J3Z9y938ANh/j/RHgIaAme0GIiMikrgHuA74GvB/Ghm71mNn60Z3MbIGZDY+23JrZm8zskWi/n5vZOSX7PhfVXY8Bg2YWN7PPmNkzUV22xczeVrL/pN8NzKzNzP7BzPZE9eH/Gr35HR37F9GxzwJvPM7nfT3wo5JrbzKzrijevcA/mVlQEu9BM7vJzOZF+492ob/WzHZHMX2q5HwXmtmDZtZnZi+a2V+d1G9lcp1T+JwiFaMEXaT8ngYKZvbPZvZ6M5s7hWPeBFwAvAx4F3BFtP03CSvHc4Hzgbce6wRm9lbgD4C3AwuAnwD/7xi7vx9oA5YD7cCHgdK74+8BPgAsBJLA70XXOD065yeja9xGmJAn3f3XgJ3Am6M72H8+wXXPBp519/wR298DXA+0AD8Hvgc8Stj74HLgk2Z2Rcn+VwH/RthD4RvAd80sYWZnAB8DLnD3FsJyfC6K/T3RF6NjPVYco6wmspXwdyUiIvXlGuDr0eMKM+tw9wzwHeDdJfu9C/iRu+8zs/OBfyTsQdZO2F38Vju8i/y7CZPIOVEd+QxhS30bYS+8f7XxnlvH+27wz0AeOA04j/CG8m+UHPumaPtG4B3H+bxnA08dsW0RYf27knDY2sejGC4FlgDdwN8eccxlwJools/Y+HC4LwBfcPdWwhv4N40ecJw6+zNHnP/HZrbXzL5jYS+HUqqzZVZTgi5SZu7eB7ySsPvb/wX2m9mtdngL9ZH+1N173H0n8J+ElS6EFfwX3L3L3buBySY6+S3gT9x9a1S5/2/gXJu4FT1H+CXhtKiV/6Eo7lH/5O5PR13abiqJ51eBH7j7Xe6eIxyP3QBcMklcpeYA/RNsv8Xdf+buRcIvAwvc/X+4e9bdnyUsx6tL9n/I3b8dxfBXQBq4GCgAKWCtmSXc/Tl3fwbA3b/h7nMmeeyc4mcg+gxzTmB/ERGpcmb2SsKk9CZ3f4gwiX5P9PY3ODxBf0+0DcKk+O/d/f6ozv1nwmFvF5fs/0V3f2G0K7m7/5u773b3ort/C9gGXBjte8zvBtF3jdcDn3T3QXffB3ye8Tr0XcBfR9c6BPzJcT72HI6ut4vAH7l7Jor3t4DrongywOeAd9jhvf3+OIrnceCfSsoqB5xmZvPdfcDd7xs94Dh1dun3oUuBVcCZwG7g+0dcu5/wRofIrKQEXWQGREnyr7v7MmA94R3lv57kkNIJ04aA5uj5EuCFkvdKnx9pJfCF0bvLwCHACFuhj/QvwJ3AN6MuZ39uZokpxvP86BtRQv3CMa4xkW7CVvIjlX6ulcCS0jvlhD0DOibaP4qhC1ji7tsJW/c/B+wzs2+a2ZIpxnYiWoCeMpxXRERmr/cDP3T3A9Hrb0TbAO4BGszsoujG+LnAzdF7K4FPHVGvLSesU0cdVr+b2TUlXeJ7CL9LjA43m+y7wUogAewpOfbvCXvETXTs80xuonp7fzTcq/SaN5dcbyvhDfMJ6+3omqOf/UOEQwOftHC43ZuOE89R3P3H0Q39HuATwGrgrJJdWoDeEz2vyExRgi4yw9z9ScKxauuPs+tE9gDLSl4vn2TfF4DfOuIOc4O7/3yCmHLu/sfuvpaw9ftNTG0Cld2EFTEAZmZRTLtGT32c4x8DTrGjx9CXHvcCsOOIz9Hi7m8o2WesHMwsICyj3dFn+4a7j7ZyOPBn0X7vtfEZXid6nEgX97MIu+CLiEgdMLMGwtbnS6Ou1HuB3wVeZmYvi24W30TYMvwe4PvuPtry/AJw/RH1WqO7lw5D85JrrSTsOfYxoN3d5wBPEN50h8m/G7xA2Do/v+Rare6+ruTY0v2PV/c9RjS3zkSxllzz9Ud8vrS77yrZ58hrjtbZ29z93YQ3EP4M+LaZNQEcp87+g0lidsbLClRnyyynBF2kzMzsTDP7lJkti14vJ6yw75v8yAndBHzCzJaa2Rzg9yfZ9++Az1q0RreFk8S88xgxXmZmZ1s4aUwfYRezwhTjeaOZXR61uH+K8IvA6E2AF4FTjnWwu3dxeDe9iTwA9Fk4AU2DhRParLdombrIBjN7e5TofzKK4T4zO8PMXh2N6xshHFdfiK79dR+f4XWix86obMzM0oRj70cn1BsbJxg93wDcNYXyEhGR2vBWwvpkLWHr+LmEid9PGL/B/Q3CoWDvZbx7O4TJ9oej1nUzsyYze6OZTdSjDKCJMMncD2BmH+Dwm/zH/G7g7nuAHwJ/aWatFk7gdqqZXVpy7MfNbJmFc+QcOZb7SLcRdiGfzN8B148OqbNwgryrjtjn/zOzxug7ygeAb0X7vs/MFkQ3OHqifUfr7cnq7P8dHb/OzM6Nvis0A39J2GiwteTalxLO5C4yKylBFym/fuAi4H4LZyW/j/DO96cmPWpi/5ewon0M+CVhRZlngmTa3W8mvPv8TTPri675+mOcdxHwbcLkfCvhDK3/erxg3P0p4H2ES8gdAN5MOClcNtrlT4D/HnVz+71jnObvgV+b5BqF6LznAjui63yVw8eP3UL4Jag7Otfbo/HoKcKxeAcIu+kvJOwefyJWEib2o7O4D3P4BDlvATrdffcJnldERKrX+wnnZ9np7ntHH8CXgPeaWdzd7wcGCbtvjyWE7v4g4Tj0LxHWW9sJly+bkLtvIUw07yW88X028LOSXY733eAawpvMW6LrfRtYXHLsnYQtyg8TTm43mRuBN0Q9CI7lC4RLkP7QzPoJv/dcdMQ+PyL83P8B/IW7/zDafiWw2cwGovNcfUT3+ePpIEz2+4BnCceivyn6TkB0w/0NhBPnicxK5n68HqgiMluZ2euBv3P3CZdPqwZRC/QvgcujO/0nevznCCe3e990xzbF698PfMjdn6jE9UVEREqV+7uBmf1vYJ+7//VJHLuK8GZ7wo9ewaXszOx3gOXuftTSryKzxYRrJ4vI7BTdsb6M8E55B/BHjE86U5WiGV7XVjqOk+XuR7YKiIiIzJiZ/m7g7ifaE23WcPe/qXQMIsejLu4i1cUI1z/tJmx13gr8YUUjEhERkUrSdwORGqIu7iIiIiIiIiKzgFrQRURERERERGaBuh2DPn/+fF+1atW0nW9wcJCmpqZpO1+1UjmEVA4hlUNI5RBSOYSmoxweeuihA+6+YJpCqlrTWZfr7zOkcgipHMapLEIqh5DKIVTOurxuE/RVq1bx4IMPTtv5Ojs72bRp07Sdr1qpHEIqh5DKIaRyCKkcQtNRDmb2/PREU92msy7X32dI5RBSOYxTWYRUDiGVQ6icdbm6uIuIiIiIiIjMAkrQRURERERERGYBJegiIiIiIiIis0DdjkEXEZH6lMvl6OrqYmRkpCLXb2trY+vWrVPaN51Os2zZMhKJRJmjEhERqR61XJcrQRcRkbrS1dVFS0sLq1atwsxm/Pr9/f20tLQcdz935+DBg3R1dbF69eoZiExERKQ61HJdri7uIiJSV0ZGRmhvb69IhX4izIz29vaKtQ6IiIjMVrVclytBFxGRujPbK/RR1RKniIjITKuWOvJE41SCLiIiIiIiIjILKEEXERGZYc3NzZUOQURERF6CctXlStBFREREREREZgEl6CJSX9yhWKh0FCIiIvJSFYthvS5SQ7TMmojUl623wq0fh/+6BZJNlY5GKuyPv7eZLbv7pvWca5e08kdvXjet5xQRkQnc8Rk49Cy879uVjkQqqNbqcrWgi0h92f0IjPRA355KRyIiIiIvxd7HoOf5SkchMq3Ugi4i9aV/b/hzcB/MP62ysUjFqaVbRKSKjdbpUtdqrS5XC7qI1Jf+3eHPwf2VjUNEREROnjsMvAjFfKUjEZlWStBFpL6Mdm0f2FfZOEREROTkZQcgNwSFXKUjEZlWStBFpL6MdXFXC7pUzsDAQKVDEBGpbv0vhj+LStClMspVl9dMgm5mV5rZU2a23cw+U+l4RGQWyg5Cpjd8rgRdRESkeg1ECXpBXdylttTEJHFmFgP+Fngt0AX8wsxudfctlYhnKJunUHRa0ompH5QbhpEocUi3QaJh6sdmBgCHVMsJxTkRLxYZ6D1AS9t8CE7+/k3vUI6mVIx4rAz3gPIZGO7G3RksGM1tC19SrC89niw8/1PY/zT07YJ5p5DLLmY4W6AhGTv2cZl+iKUgnpz6tYYOQSEbPm+YC/FUeKp8gWy+OPW/uUw/7HoYgjgsOQ+SjWNvuTsHBrK4O0FgtDclMbPDDh/JFcgXnebU4f+F5AtF+kbytDUkiAWHHzMmOxiuQ55unVqsx3Hcci7kwYLwb6Rk5vZC/z4mOUpERERms4GoR5xa0KXG1ESCDlwIbHf3ZwHM7JvAVcCMJOhv/7PvcNrI4+z52T+RzvWSzTstNsSy4BAtsRz9yQUMpDroKsxjd76ZxfEBlsd7aW8w2hvjJA49RXPPVmJeACBDkmfmXEL/issZbl6JJxpZPvIUHf2baRzeTTCwl2xmhKFMnlSum8biIAAjsWYONp/Orak3ccvIeSxuibOueYBLF2U5d26WoHEuB2weu57dSua5e7FiHlqXQhCD3l2ke59h5fBm5tJPljh9iQUMNywi17SE7vgCdns7B4L59MQXYsMHWND7GPPz+2hIxEglAgwoDg3zvZ98kcFMgYO0MZBaRDGWwnBWeBfrCk+RMOeFpvUcaD2LnkQHhUKONQfuYe3IL0lagSAW47mml/FY6yYSTXNYGT/EiswzdPQ+Srp3O/HhAwAY0AxkidMfbyeIJ4kFxu74cu7Pn8ZThaXss/msaBhhU+MOlgUHMIxC0RnO5slkR2gY3kdL/iDpmJOKB+TT8xhKLyJWzNIwvJdiscCh+AL6gjk0JOM0JmM0Rp83kyuSGR5gwb6fkc6Hay/miJMgzwZv5js/uZhsyzJaWucwt3CQxkIfA7G5ZGKNnNF/H6cOPgI4A/G57G4+mz3LXk9v40qyB3eSHNpNW24/LcVeGhIxmizD3O7HacvsPuxvbyA+l35vIJMvMuQp9ls7w8m5NCQTpKPfiVtAf7ydgfg8VhR3smroCeb0byOgCEDR4uxvO5vHWjfxH8UN3L07QWaon3fH/oO3xX7GUJAllYjR1bSeR1pfzT2Dq3lgb555hUO8Lf0gZ8dfCP9uizGez7axx+fgFqM1naBYyPHAz3/I6uJO1hWfYllxN62E3YEGaeBAbAGZxkXEWxdhQRyKOWIDL5Ia2cdwrJmexEJ6mtcw3LGB+U0xlg88QWPvNry3i9xwH89nWnku20JbUwNL21sJLvsDTjvlFLbu6eP2J/awvz/Drz//GeY2pVn84ZvJ9uwiCWQ9xuCB3cwt4/8LIiIiUkajc8loDLrUmFpJ0JcCL5S87gIuOnInM7sWuBago6ODzs7Ol3zhWH6Ibw9/kAAnl4vTH7QRpCBrKQ5YO/t8Dm2ZQ5wxso1L6B077hCtjHTHyQLbiov4pb+RweR8GhMBy/M7eXn3/aztOTy+Q97M497BPuYx5PMwIB9fS39yPtkipDMH+JXuR/lI8D/4ACnSfZnwwKfGz9ERPbIeJ0+MxhfDfTKeYLct5LHURnrSyymO9JLKHGB+5iCLex7gbDvEBiscFk8Ro9vmUMhalOqF4mYkkwWain3ECkWIDssTY0dsNXkP2NT3XVJ9/zZ2TIYET8TX01NsJJbNcEH2bi7q/v7Y+zmPsdlXsrV4Nru9nUO00tEYsLSxQGz4IPFsN/lMgTgF1gXP8n772XhAI1A8ZOxjDkXCVt1GAAvotrl0xZbSl4uTHSkyb6CPxfYYOeI85fMoELDEulhiW3FGP0f4ADACbiuew39wETtTZxCkW3l57EneMPI93pb9OY1DQzAEeQL6aWRulJw+x2L+ibeQI8bi3AEu7n6UM3t+dFj55ohxyFspYOQ8zk99FU/apRwqNGIUmUc/y4sHmRfP0tJgNDPM6vwBGvPPU8z52O8kToG59BHD6fcGHimeysP+Vp6wNQRe4GU8zWWHfslrez7Pa4ECAcV0jAQ5nkudyQu+gmw2y4aen7Kh504+BIwk0yQ9Q4DTXZhDkRgJsrTG+8c/wGghZaObTvFTuTdxCQeDdooEtBcP0ZY/QEvvAZr6nsFwigTs9zkctAW02SAdvplze++BXdHfnBvPeQe7vZ1B5rEq3s2mZBeFkSLtXd18/Wu9vLHwAfIOgcElqWdZy8/p7mvmf3/9LlYc/DHvA7b7MuZ2756W/wOmYmBgYMauNZvNlnJoa2ujv7//+DuWSaFQOKHrj4yMzIpyExGZVfpLWtDdwY7Rc0+kytRKgj7Rv0g/aoP7DcANABs3bvRNmzZNz9Xbv8TDOwc4/40fYF7U5Rhg4ZH75TMwdBAa25kXT7Gvf4RHX+hlbmOCDy5tI50Y73Cby+XY8/xmYv27KY70sju9hh2FDvb0jfBiX4b1S1t53dpFzG0a7x6dyRcYyeRg512kn/0RNHeQb1nC5oEWfro3YK6FLfcLlp3K6rMvoSGZprd7P/l8jnkLlrA6CFh9ZMiFIgcGsuTTAcnsIejdBX1dkGohWLqR9iO6KXd2djJWroV8uNZ01CU73ryINYn0eFkcfCbsEp7PkDrlUjaUdtHPDcOOH+NepCexkF3BUl4chLaic2ZbmlXtTYd99tFYDw1mmdeUhEwPHNoxFmt24XnkcuHvJhELmN+cJB4LWFJy/MGBDEPZ8G5CEjgNaEzGmBd18R7K5tnTO8KenhEODmaY35xicVua17c18PbDuli/ns7O82jctCnsSp4dJN60gLlBLOwOP9zNquaFfKikIvFCnr7tP8OGDtK8YCXWtoxE0wI6goCRXIGeoRyvbUryxnhAoegcHMjQmIof1cX8mAo5GDpIY8N8zhjKc24yRks6gbvTN5wnWyhSHNpB8MLPifXuIpYbhnPexaol57JqrICzsOPHsH8r6d5d0NgO697K3PlrSn5vI+Hv3MPbA/fddz8XX3wRqdalrI0lWDtRaEVnT+8wxahuPas5ddi/BR/qpv+Z+zg4XGBH6iyGrZFFbWnOam+kvXn839vAtz/Ge7d8k0PrP8aiZadwxbpFzP3+h2ArzLUBvr9lH28LDkAMhuavZ/nBe7jwklfSmCz/f4OH/buoY7OlHLZu3UpLy0sfEnSy+vv7T+j66XSa8847r4wRiYhUodLVWIoFiNVKWiP1rlb+kruA5SWvlwG7j7Hv9DvvffT1do6NBz6meApax1PChS1pXrs2PeGuiUSCxaedC5wLwCLg/OOEkYrHSMVjcNabwwfhL/hl0WMibe0dk4ccC1jUFsWYWgQti4ANx4kkEosf9nkPP3EKOtaGj4kkGuD0KzBgbvRYf5zLxWMBC1ujWBvnhY8o1jSH/4FMpL05Rfsk7zcm45y6oJlTFzQf50wlUi2Hzw0QT0LL0WVusTitZ1w64SnSiRiL2sYT1lhg459zqmIJaFlEDFjYOv7P3sxoa4zGrbecCR1nHvsc8SSseU34OJZEGuasGHs50vAczF01eWiBsWxu4zHft8a5tJ79elrhqBtIpZov/2+w5f/xyYbb4cI/gwPbYev3YPlF8ML9XNp2gIUD3RSTzSxccSYth37AbZtf4A3nTXZWERERmZVGx6BD2IquBF1qRK3M4v4LYI2ZrTazJHA1cGuFYxKRmTR3Jbzs3fDQ1+CRb8Adn4FYEt701wD80csD3rEmRtCymGXLVgLwk19urVy8Uve6urq46qqrWLNmDaeccgof+9jHyGQylQ5LRKQq+Ogs7kA+p/87ZeaVqx6viQTd3fPAx4A7ga3ATe6+ubJRiciMe9Wnwm5u3/0IbL8LXvnJsJdG43zSh56iKbMPWhcTtIQDULY9+yz9I5pcRmaeu/P2t7+dt771rWzbto1t27YxPDzMpz/96UqHVlFaMlVEpirfO96C/sze3kn2FJl+5azHa6YviLvfBtxW6ThEpILmrYbfvi/s6ta6dHwpt4Vnwb6t4Xi1lZdA0wIAWoo9bN7dx8WnTDa4QWT63XPPPaTTaT7wgQ8AEIvF+PznP8/KlSu5/vrraW4+gaE0NaKSS6a6l0xbMzp/ysC+cIhS0wLysTTdw+Hykol4jEQsIBkLiAV29LxU7jC4P+zBk24Nl3kE4oFhuaFwucxYEhINeLKZghOdJzpRsRAec8SJ3R13CI5YwjKTL7CnZ4SWdHxszhQI5/fY3zvI4GA/zUGOZoZoyh2CkT5oXhj9H9kWDjnLZ2CkB4oFEtkePDtEXz5B30iOXGaQxMBuFhQPkM71Qsd6CvNOY/v+QTbv7iWdiLGyvZGV7U1j86IUij528zNGgeZkDLPgsC7IhZEBRjzOSMEYyRcZyRUoFp1k4KSKgyQSSZLJJKlkmkQiftRyn6Of/cBAlv39GfKFIitaYyyI9WOJRkg2jy1jWiw6megaI/kCRYeYGUEQ/owFRmAQw4nF45jBYC6cH6UlnaApGTvs+sf6XQBh+Y70UsgOYek5BM0LJl0KdiST4cXdz5OKQVMqQVPbfIJ0y1jcZmD5kfDvItl07InQigXIj4RzziQaj17C1f3wv60JzlMshv8OgsDCfwf54fFjJ5DNF+kZHMEx0ok4qURAKh5gZhSLjgMxI5yXJoiRzRcZzhYYyuZIWYGmWJ5UQ8v438XodSb6jE/dAadcOr4McSFHYuQg+72NBdbL1l0HOeOUlccqZpFp96Mf/ahs9XjNJOgiIgDMP+3obQvPCru95zPQungsQZ9vvXQPZmc4QJlVbv8M7H18es+56Gx4/Z9OusvmzZvZsOHw+TxaW1tZtWoV27dv59xzz53emKpDxZZM/dn3v0b7L77A/s4e5tFL7LC1ScIvSwtKXhfcKBLghCuaOEYvTQx6mkXWTaOFXRyLbvTRSI8302BZOqz7sPNmPUE3zcQpkCZHyrIkKFAgYIQUw5ZmyNPk3UiRJUmWBsuRIE+RgAIxch7QRECOGLuJkbQCaTKkPMOiI1ZfmUjBjZiNJ2CvAPg5mDfSSIx2O3rFgT5vZtAXkfZ5tFsfHbabBENkLVy1Y7+3kfEEi+wQLTYwdtwwKQZopNGHaLIMaTd6mcuAN+IYzTZMB90kjlw1xo0cMfLEKFiMPHFyxMh6jLzHaCZG2rLM5yBW8lmyHmOEcKnXJHkgRcabKBCQshxJ8sTJkiJH2sIbCnkPGCHJRSTJ/DRBH84QRRJWJEYhfHj4O+qzZgasheF4Cx4kWJLbyYJiuBTs6MwxGU8wRBosnNE4MKNoAcOkKbqzsHiAlUd83iFPkSEJOA1kxmMjRr+10EczfZ4mTpEkWebSxxz6o7/IUC/NZC1JysO/myS5w94vEFAseRQIyLsRo0ia7GG/g5eTYP+PW+kL2hgIWsgUjWKhwILiAZbbPpJWYMQTjJCkhyRO+PeaJkeaLIE5WY8zTJIEBTqibRCu0rPbFuIWY6Ef5FCsnc82/CGHkkt454ZlvOGcxWx54D/Y9JP38NWGD/JP/mY+fOkpvG9tAgMGUh0syPby5K5Dk/2ZS62rQF2+devWstXjStBFpPYtPAuy0ZfElpIEnT4ODSlBl5nn7hO2CPoxWqrqRMWWTM10H6At1cKTsVXsZx4HmMt+5tAaDLMw6KXZ8qRjTsyKuIN7EffiWItfQIGG4hCp4jA7Y3M5FO/AKNJYHBh7ZDzBPb6QQ95GU7xIa5ChzXtoLg6QI06GJCMkyJDEinkSxREaGKGRERJWpBCkyFuSIU8w4nEMJ06BxliRxlgRLxbI5/NkiZO1FMVYingiBbEUIyTp8zS7Cm0czDfQYT0sskOkfZiUjzBCiiFrIk8My4/QFs8yn17SluOJxHx64vPZ5e0cyDeyKv8sp+a3scT3carvIhNrZnf8Ag54C4M5SBRHWGC9NFiOp+Nn0Ru0MZgPyBaKNDFEK0NkgwaG4200WIZ5hYOkfZjAoCdI8Xysnf6gNSzfYgEr5sELWLEAnieInictTzoojD0GLEGndfCizyXuWVLFEVKeIekjWBCAxUiTpckHMIr0kyBnSXKWIEeCvCUoEBB4jkQxS7yYoTFWIFeEkWJ4IyRPDLcYsViMuOdJFAZJFwZoKAyQyA+yJXYGu1OvJZtog1iKJu+nLX+QRHGEokO+CNkiUCzQZBmSVmBL6hJyjQvIESeXdxL5fhryPWFCbeGyvb3eTLZoJAsDNBYHmWsDNDFMxmIMkOD54Cz6rI0RS5MnRtqHaSv2EPccWQvT8wxJ8hYD98NTcw9/JgOnIVbELRb+LXqCEUviRUjne2j1AZqL/TQX+mkwJ4gb/YmV3Je8iIIlCIpZYsUMQTGHeZF8kCRnSUZIkvUYDWRptAwexPFYGNOQJ0jl+pmX34sXCzxhZ/Mr2Z/wV4Of5ZPZP+Rz3+vjc9/bwmfi32BTHC7O3ss34q/jD2/ZTPejO/k4MJKYC1n45fZdZV+OcrYsFVpps6UcSpdMTeWyBIX8cY44McVclswkS6IWi0VyudxRy6YWCgUGBweP2n4iS6YqQReR2rewZLWAlsWQbMSTzczPqwW97h2npbtc1q1bx7//+78ftq2vr48XX3yRM844oyIxzQIVXDJ1E52dF5R9GcBLynr26XEyyyEetaxshUyyDskJ6+zs5LwTLIfTp/H6s8mMLpG55zG48S18PfF/ePRdt/OfO4b59ceegH5YX3ya731kI1f94xYe2XkAkrDqjJfBw/dzYCjPxa941WHLtE632bJUaKXNlnI4bMnUt/xVWa6RnOS9tWvXcttttx22bGpfXx/79+/n/PPPp6Gh4bD9T2TJ1JqYJE5EZFILSr62RUv/WdN8OmL9HBrUJHEy8y6//HKGhoa48cYbgfCO+6c+9Sk+9rGPHVWp15HKLpkqIpW3+Bx497egr4uX7foWnzynQLr/OTj3veAFmnZ28nfvO59l8T4AGuaH484Dz7N5d18FA5d6s2nTprLV40rQRaT2NcyBljAxp2Vx+LNpIYtifRwa1NIsMvPMjJtvvplvf/vbrFmzhvb2doIg4Lrrrqt0aJWkJVNFBFZcBKe/Hu79Ejz6DcDg1f89HJ729B2ctrCFj18UTQIb3XRPkOfRF3oqFrLUn3LW40rQRaQ+LDwTMGjuCF83LWC+9XFoSC3oUhnLly/n1ltvZdu2bdx2223ccccdPPTQQ5UOq2K0ZKqIjNn0mXBlgZ9/CZZdECbia64Il1At5Jjv3dAwN5zZHljYFOOxrp6Khiz1p1z1uMagi0h9WPO6cPmZ0eVcmhcw13s0Bl1mhUsuuYTnn3++0mFUnJZMFREAlpwLZ7wRnvoBnPWmcNvpV8Aj/wrP/RQGXoTmRRCEdfqZCxu4s0troUvlTGc9rgRdROrDxR8JH6OaFtBS7KNnYLhyMYmIiMjELv9DGNwH698Rvj71snB9+395W5iYr7wEYgkAVs1J8tyOQYpFn3h9epEqogRdROpT0wICiviw1k6tR8da5my2qfNl10Skni08E37j7vHXqRb4zXtgy63w/M9g3dsgCBP01pTjDv2ZPG0NiQoFLDOtVutyjUEXkfoUrYXemOtmJFeocDAyk9LpNAcPHpz1ya+7c/DgQdLpdKVDERGZHRacAZf+N7jmu7Dh/WNd3JujnLxvWPPK1ItarsvVgi4i9SndBkArg3QPZVncVrdLW9WdZcuW0dXVxf79+yty/ZGRkSlX1Ol0mmXLlpU5IhGRKhUbTdDDJK13OHfYWo1Su2q5LleCLiL1KbrrHsM5NKgEvZ4kEglWr15dset3dnZy3nnnVez6IiI1I+ri3hQLE3S1oNePWq7L1cVdROpTEAt/WJHuQVXoIiIiVSeaJK4pHiXoI6rPpfopQReR+jTWgl7k0JCWWhMREak6UV3eWNLFXaTaKUEXkfpkYQt6nILWQhcREalGUQt6Y0wJutQOJegiUp+iLu4xK3JQCbqIiEj1icagp6xALDD6hvMVDkjkpVOCLiL1KUrQW5OmFnQREZFqFLWgWzFPazquFnSpCUrQRaQ+RV3cW1OBxqCLiIhUo2gMOsUcbQ0JJehSE5Sgi0h9iir1tpRa0EVERKpS1IJOIUdrQ0KzuEtNUIIuIvUp6uLekgo4pARdRESk+kRj0NWCLrVECbqI1KfRMegJo1td3EVERKrPWAt6nlYl6FIjlKCLSH2KxqA3p4zuwRzuXuGARERE5ISYhfV5MU9rOqFZ3KUmKEEXkfoUjUFvThrZQpHBbKHCAYmIiMgJiyXGurj3DeuGu1Q/JegiUp+iLu7NUe84TRQnIiJShYIEFPK0NSTIFoqM5IqVjkjkJVGCLiL1abSLe8IANFGciIhINYrFoZijtSHsGaeZ3KXaKUEXkfoUtaA3Ri3oWgtdRESkCgUJKIRd3AFNFCdVTwm6iNSnKEFvilrQD/RnKhmNiIiInIwgPjYGHZSgS/VTgi4i9SmaJK4tZSRixjP7BysckIiIiJywWDxcZi0dJuh9StClyilBF5H6FI1Bj1Hk1AXNPP1if4UDEhERkRMWJNSCLjVFCbqI1KeoBZ1ikTUdLUrQRUREqlHs8DHoakGXaqcEXUTqUzQGnWKeMzqa6eoeZiCTr2xMIiIicmKCBBTztKTDG++9w6rLpbopQReR+mQGFoAXOL2jBYBtakUXERGpLrE4FHLEYwHNqbi6uEvVU4IuIvXLYlDMlyToAxUOSERERE5INAYdoK0hoXXQpeopQReR+hXEoFhg+bxG0omAp9SCLiIiUl1iCSiE3dpb0mpBl+qnBF1E6lcQh2KBWGCctnB8Jvf/77tP8MGv/YJvP9R12J14d+fgQAZ3r1TEM+JkPqe7M5Qtz7g/d+fQYJaRXKEs5xcRkSoWrYMOYQu6EnSpdvFKByAiUjEWAw+TvtM7WvjZ9gP8cmc3/3Lf87Sk4tzz5D6S3wn4ldPns2JeE3du3suunmEWtqQ4b8UcVsxrZMmcBtYtaeOcZW2kE+HEc73DOX65s5t8wXnlmvlTCsXdeXhnNy8cGmZRW5pTFzSzoCUFQPdgls6n99GaTrBkTgOnd7QQC+yY58rkCzyxq4/Nu3vZ1TPM/r4MBXcMOGVBMxtWzmVNRzPzm8LzHxjIsLt3hD09wzyxu5cfPLaH5w4O0d6U5PyVc3ntWR1cftZC7nv2EP9873PkC0XOXzGXDSvDx+7eEf7X97fw0M5uXnNWB7/xytVsXDWPWGDsODDI1+97nv0DGV58cYRf5p7mTecsZk00rKBU30iO/3xyH43JOPOaktz37EFuf2IP214cIJMv0t6U5L++7nR+deNy4rGj7y+7O88fHOLxXb2snt/EuiWtmNnYe4919fLE7l4A4oGxsDVNYyLGPU/u454n95FKBCxua+CKdYt4+3lLCYLxY7fs6eOZ/YOcvbSNVe2NY+cVEZEKiyUgE95gb2tIsPPQUIUDEnlplKCLSP0KwjHoAGd0tPCdh3dx/Q+2MrcxwU9+/9Vse7Gf7z+2hx88tofOp/bzqjXzee/FK3h6bz+PdfXS+dR+MvkiECZ8rQ0J3J3uofG7903JGOvmwfPJ5zh1QTNb9/Tx+K5estFxc5uSLGxJ0fn0fh59oeew8C5YNZdV7U1877HdjOSKY9sXtKR4/fpFtKTj7OkZIQiMJW1phnMFHt7Zw+NdvWQL4f7JWMCClhSJmJErON99ZPfYeRKxMMnMFcZbygODS06dz7suWM4z+wa5f8dB7try4tj7q9obmd+c4sb7nuerP90xtn1+c4r3XrSC7z+2h7u2vEhzKs4pC5p4fFcviSBgyZw0g0NF7r9nG1/4j22c3tHMm85ZwgWr5nFgIMMvd/Zw04MvHDWT/vkr5vD+S1bR0Zrmzif2ct3NT/C392znolPaOXVBE/v7o5sLvcN0dQ/TU1L2K9sbOXNReCNgy54+Xjg0POGfQTwwXn5qO7HAePrFfu7a8iJf+/kOXn3GQvb2jfDgc908e2BwbP95TUnOXzGH9UvbGMzk2duXIZcv4oS/+z29wwxmwhs/qXjAorY0S9oa+F9vXc/cpuSEMYiIyEkqGYPe2pDQMmtS9ZSgi0j9isagA2MTxT34fDf/7YozaE7FOW/FXM5bMZfr3nAW2UJxrIV8lLtzYCDLY109PLyzm75oaZeFLSk2rJxL0eEHj+/m9ke7eODWzWPHLZ3TQHMqTtGdQ89lOTiYZVV7I//zqnVcfEo7L/ZleHhnNz94bA+3PLKbq85dwnsvXom789zBQX64+UW+9YsXyBedRa1pCkVnX/8I8VjAOUvb+MArVnH+yrm8bNkcFrakxlqCAXqHcjzS1cPzBwfZ3TMCwJI5aRa3NbC4Lc3yeY1ja8mOfsbHd/Vyz5P7OHNRK69d20EsMDL5Alt29/HQ890Uis57L15JcyrOdW9Yyw+37OXB57rZuqePj112Gr/28pUsbEnT2dnJ2g0Xc8cTe/n+o3v4/N1PM9qLPhYYbzpnMde8fCWxIGBf3wjrlraxdE7DWCwffMUq7ty8l+/+cjc/2XaAm3+5i5Z0nCVtDSyek+bspXM4e2kbZy9tY8ueXn7w+F6eOxC2pJy6oJnfefUaXnHafBKBkckXebFvhJ6hHBtXzWVOY5g4F4vO9x7bzZ/f8RR/85/bWdCc4oxFLfzGq07hnGVtPL6rl4ef7+ahnd3cvXUfqXjA4rY0qXj4t9HWkOD8FXNpSccxjKFsgb19w2zd00dD8vC/HxERmQax+NgYdHVxl1qgBF1E6lcQH+/iHrW0tqbjXPPylYfvFhjp4OjkysxY0JLi8rM6uPysjgkv8co183nd3IOcft7FPLt/gDMXtY51XR+VyRdIxoKxbtNrOlp45Zr5fPzyNRSKflh39vNWzOVt5y0jmy8SC2zsvVyhiDsk45NPLdLWmODS0xcACybdr/QznrNsDucsm3PY9lQ8NnYDo1RDMsZV5y7lqnOXTni+hS1prnn5Kq55+Sr29o7w9Iv9dLSmWTInTUs6MeExpbFcuX4xV65fjLszkiseM+k9e1kbv3rBiknPt3xe41HbgsC46tylvPmcJeSLflR5rl/axrsvDM87kiuQigfq7i4iUklHzOI+mC2QLxQnHAolUg1mXYJuZv8HeDOQBZ4BPuDuPdF7nwU+BBSAj7v7ndH2DcDXgAbgNuATXuuzOInIS2fjLehL2tKctbiVd25YdtxE8YQvY8bSOQ2HtQaXGm19ncixxpofmTgmqvCLyKK2NIva0id1rJmVtUU6CIzkJOP8gaN6VIiISAXEElCIurinw9SmbyTPPA0pkio1G7/R3QWsd/dzgKeBzwKY2VrgamAdcCXwZTMb/Xb0FeBaYE30uHKmgxaRKlTSxd3MuP0Tr+KDr1xd4aBERERkyoLE+M326Eb40yXLpv58+wF1e5eqMusSdHf/obuPzhJ0H7Asen4V8E13z7j7DmA7cKGZLQZa3f3eqNX8RuCtMx23iFShkkniREREpArFxpdZu+S0+STjwdjkpk/s6uU9X72fD//LQxSK6lwr1WHWdXE/wgeBb0XPlxIm7KO6om256PmR20VEJleyzJqIiIhUoWC8i3tzKs4rTm3nri0v8t/feBbfeXgXZnDvswf54n9s4yObTuU7D+/ix0/v57GuHtKJGJ++8gyuWLdo2ucT6R3OMZILv2O0NSRm1bCoYtHJFYsUi0zLcDF3p+iQLxYpFJ14EBx3TpwTsa9/hEd29hALjDmNCU5b2HLYhLbl0DuUoyEZm9bPMVUVSdDN7G5g0QRvXefut0T7XAfkga+PHjbB/j7J9omuey1hV3g6Ojro7Ow8scAnMTAwMK3nq1Yqh5DKITTby+GC4QxDL+5lc5ljnO3lMFNUDiGVg4jINIolDusN99q1i/jPmx9n8+4+bn10F69b20FTMs4X79nGv9z3PIcGsyyf18CGVfN4em8/H/7Xh3nZsjbOWzGX1fObaG2Ik4rH6BnKsa9/hB0HBnlm/wBdB4YYuvt20vGAMxa1cHpHC2csamFJWwP7+jPs7hlmd+8wu7qHeWb/IAcGMuMhBsYp85s4dUEzC1tTNCRj9A3n6R3O0jucG1sFJgiMmIX7tzUk6WhNsag1TUdrmkTc2N0zQvdgFrPRfQ2z8GbAocEshwazdA/mcJzGZJyFLSnOWtzK0jkNDOcK7O0b4b5nD/J4Vy/5qEfB0jkNbFgZrj4ylC0wmMkzlC0QC4wlc9LR0nV5+oZz9Axn6do3TP6+e+gbzpEphAn5RL0T5jenmN+cpFB0coUiuYKTLxZpb0qxZE6adCKGEybCu3vCZVCXz2tkVXsjK9qbaE7F+OXOHu7fcYgdJUudApjBuiWtrFnYQlMqRiIWkC84+aKTj2LKFZ1CsUi+EMY3tynJ4rY0hwazbN3Tx/6BDLm805CMcUZHCyvaGxnI5Nnfn+GJXb3s6Q1XumlvStLRmqajNcUrTpvPb7zqlGn9851IRRJ0d3/NZO+b2fuBNwGXl0z21gUsL9ltGbA72r5sgu0TXfcG4AaAjRs3+qZNm04m/Al1dnYyneerViqHkMohNOvLYWsrTXPmlT3GWV8OM0TlEFI5iIhMoyA21oIO8Jq1C7nuu/BHt27mwECW/3L+Ml5x2nxe6B6iORXnty49lYtWz8PMyBeK/L9fvMC3H3yBf3vwBQazR/eqWzqngVMXNjPPhjjrlBUMZPI8/WI/tz66m/77x28MxAJjUWuaxW1pXn3mAk5d0ExLOoHj7OkZYeuePrbt6+feZw8ylM3T1pBkTmOCtoYE7c1JDCh42LqdLxbp6h7ioecP0T10+Pj5xmQMdyi4Uyw6RXfaGhLMbUrS3pRkZXsjgRmD2TzP7B/g7q0vMpo/xwPjnGVtfOiVq2mNWqC37O7jF88dIpsv0pSK05iM0ZSKk80X2by7l77hPK0NCdoa4sxpTDInZZy6bB6tDQlSiYB4YMSC0Z9GPDCGcwX29IxwaChLImYkYgGJWEBgcGAgS1f3MNlCEYDWdIKzFrcC8PyhQR5+vpv+TD56L86Fq+fx7guXs2HlPOKBcWgwy6NdPdz7zEEefP4QQ5kC2XyReMyIx8I44jEjXhJTYMbm3X3s6x+hKRXnrMWtbFw5j2QsoG8kx9Y9fdzz5D5a0nHmNSW5cPU81i5uZSRXZG/fCPv6RtjbN0JX9/B0/dVOatZ1cTezK4HfBy5196GSt24FvmFmfwUsIZwM7gF3L5hZv5ldDNwPXAP8zUzHLSJVSGPQRUREqlvJMmsQLud57vI5PPR8N/Oakmw6YyHJeMC/ffiSow6NxwJ+7eKV/NrFK3F39g9kGMwUGMkVmNOYoL0pNdbFOby5etbYse7Oi30Z9vQO09GaZmFLqixLu43kCuzvz5DJF1kyJ01j8sTSt+FsgQMDGRqTMZrT8UlXjpmKsBzOfUnnmIy70z2Uo2coy6r2JoIJVlS57MyFfHLS5t6J5QvhErWzfXnUWZegA18CUsBdUeHd5+4fdvfNZnYTsIWw6/tH3ccGj36E8WXWbo8eIiKT0xh0ERGR6jbaxd097PsMvHZtB7/c2cNbXrZkymOIzYyFLWlomdplzewlLRc6VelEjOXzGk/6+IbkSzt+ppkZ85qSZVkmrxw3UMph1iXo7n7aJO9dD1w/wfYHgfXljEtEalAQH1uaRUSmh5n9H+DNQBZ4BviAu/dE730W+BBQAD7u7ndG2zcwfqP9NuATJUPcRESOLYgmCyvmw2QdeMvLlnDrI7t538UrKhiYyMmpjtsIIiLloC7uIuVwF7De3c8BngY+C2Bma4GrgXXAlcCXzWy0r+VXCCdxXRM9rpzpoEWkSsWi9saScejL5jZyxyd/hdMWTrE5XGQWUYIuIvXLYuDFSkchUlPc/YfuPnrn6z7GJ3K9Cvimu2fcfQewHbjQzBYDre5+b9RqfiPw1pmOW0Sq1FgLem7y/USqxKzr4i4iMmOCGORHKh2FSC37IPCt6PlSwoR9VFe0LRc9P3L7hMq1ZKqWvwupHEIqh3GzvSyWdj3HGuBnP/4RuWRr2a4z28thpqgcQuUsByXoIlK/gpjGoIucBDO7G1g0wVvXufst0T7XEU7q+vXRwybY3yfZPqFyLZmq5e9CKoeQymHcrC+LXzwD2+EVL78QWib6b2l6zPpymCEqh1A5y0EJuojUryCuMegiJ8HdJ13gxszeD7wJuLxksrcuYHnJbsuA3dH2ZRNsFxE5vmhiuNIx6CLVTGPQRaR+aZk1kWlnZlcCvw+8xd2HSt66FbjazFJmtppwMrgH3H0P0G9mF1u4vuo1wC0zHriIVCeNQZcaoxZ0EalfQQyKmiROZJp9CUgBd4X5Nve5+4fdfbOZ3QRsIez6/lH3sTtkH2F8mbXbo4eIyPGNtaCrR5zUBiXoIlK/tMyayLRz99Mmee964PoJtj8IrC9nXCJSo4IonVELutQIdXEXkfoVxNXFXUREpJppDLrUGCXoIlK/TC3oIiIiVW1sDLrqc6kNStBFpH5pDLqIiEh1i0Vd3NWCLjVCCbqI1C+NQRcREalumsVdaowSdBGpX1pmTUREpLrF1MVdaosSdBGpX0FcFbqIiEg1C7TMmtQWJegiUr+CGBTVgi4iIlK1glj4U13cpUYoQReR+hXEwTVJnIiISNXSMmtSY5Sgi0j9skBd3EVERKqZllmTGqMEXUTqVxBXF3cREZFqpmXWpMYoQReR+qVl1kRERKqbllmTGqMEXUTq1+gya+6VjkREREROhsagS41Rgi4i9SuIusVpojgREZHqpDHoUmOUoItI/Qqi/wI1Dl1ERKQ6aQy61Bgl6CJSv0Zb0HXXXUREpDppDLrUGCXoIlK/LBb+dLWgi4iIVKWxMei62S61QQm6iNSvsRZ0JegiIiJVaawuVwu61AYl6CJSv4KoBV0JuoiISHUyC5N0jUGXGqEEXUTqV6Au7iIiIlUvSKgFXWqGEnQRqV+jY9A1SZyIiEj1iiU0Bl1qhhJ0Ealf6uIuIiJS/YK4WtClZihBF5H6pWXWREREql8soTHoUjOUoItI/RpbZq1Y2ThERETk5AUJ3WyXmqEEXUTql7q4i4iIVL9YXAm61Awl6CJSvwJNEiciIlL1tMya1BAl6CJSv0bHoGuZNRERkeqlZdakhihBF5H6pWXWREREql8srmXWpGYoQReR+jXWxV2TxImIiFQttaBLDVGCLiL1S2PQRUREqp+WWZMaogRdROrX2DJrGoMuIiJStbTMmtQQJegiUr9GJ4lTpS4iIlK9YprFXWqHEnQRqV9aB11ERKT6aQy61JBZm6Cb2e+ZmZvZ/JJtnzWz7Wb2lJldUbJ9g5k9Hr33RTOzykQtIlVFy6yJiIhUv1hCs7hLzZiVCbqZLQdeC+ws2bYWuBpYB1wJfNlsdAApXwGuBdZEjytnNGARqU6mFnQREZGqF8TVgi41Y1Ym6MDngU8DXrLtKuCb7p5x9x3AduBCM1sMtLr7ve7uwI3AW2c6YBGpQuriLiIiUv00i7vUkHilAziSmb0F2OXujx7RU30pcF/J665oWy56fuT2ic59LWFLOx0dHXR2dk5b3AMDA9N6vmqlcgipHEKzvRyaBnZwAfDE449yYG9j2a4z28thpqgcQioHEZFppjHoUkMqkqCb2d3Aogneug74A+B1Ex02wTafZPvRG91vAG4A2Lhxo2/atGkq4U5JZ2cn03m+aqVyCKkcQrO+HF5cCA/C+rVnwrpNZbvMrC+HGaJyCKkcRESmWSyuMehSMyqSoLv7aybabmZnA6uB0dbzZcDDZnYhYcv48pLdlwG7o+3LJtguIjK5sWXW1MVdRESkaqkFXWrIrBqD7u6Pu/tCd1/l7qsIk+/z3X0vcCtwtZmlzGw14WRwD7j7HqDfzC6OZm+/BrilUp9BRKqIxqCLiIhUP41Blxoy68agH4u7bzazm4AtQB74qPvY2kgfAb4GNAC3Rw8RkcmNJejqFiciIlK1goTqcqkZx03QzawR+BSwwt1/08zWAGe4+/fLHVzUil76+nrg+gn2exBYX+54RKTGjC6zpnXQpcZVsi4XESm7WFwt6FIzptLF/Z+ADPDy6HUX8L/KFpGIyEzRGHSpHzNel5vZ75mZm9n8km2fNbPtZvaUmV1Rsn2DmT0evfdFO2IZFxGRSQVxtaBLzZhKgn6qu/854XJmuPswE8+cLiJSXdTFXerHjNblZrYceC2ws2TbWuBqYB1wJfBls9FuLHyFcBnUNdHjynLFJiI1KIiHveF8woWcRKrKVBL0rJk1EC1dZmanEt6FFxGpbqMt6F6sbBwi5TfTdfnngU9z+LKnVwHfdPeMu+8AtgMXmtlioNXd73V3B24E3lrG2ESk1owNWVN9LtVvKpPE/RFwB7DczL4OvAL49XIGJSIyIyy6R6kWdKl9M1aXm9lbgF3u/ugRPdWXAveVvO6KtuWi50duP9b5ryVsbaejo4POzs5piXtgYGDazlXNVA4hlcO4aiiLFc/v5BTgR5334EGiLNeohnKYCSqHUDnL4bgJurvfZWYPAxcTdof7hLsfKEs0IiIzScusSZ2Y7rrczO4GFk3w1nXAHwCvm+iwiUKbZPuE3P0G4AaAjRs3+qZNm44X7pR0dnYyXeeqZiqHkMphXFWUxU8fgR1w6StfAcnGslyiKsphBqgcQuUsh2Mm6GZ2/hGb9kQ/V5jZCnd/uCwRiYjMlLFJ4tSCLrWpXHW5u7/mGNc7G1gNjLaeLwMeNrMLCVvGl5fsvgzYHW1fNsF2EZGp0ZwyUkMma0H/y+hnGtgIPEp4l/sc4H7gleUNTUSkzLTMmtS+Ga3L3f1xYOHoazN7Dtjo7gfM7FbgG2b2V8ASwsngHnD3gpn1m9nFUUzXAH8znXGJSI0bm1NG9blUv2NOEuful7n7ZcDzwPnuvtHdNwDnEU7sIiJS3cZa0DWpjNSm2VSXu/tm4CZgC+F4+I+6j32b/gjw1SimZ4DbZzI2EalyWjZVashUJok7M7ojDoC7P2Fm55YvJBGRGRJokjipGxWpy9191RGvrweun2C/B4H15Y5HRGqUJn2VGjKVBH2rmX0V+FfCSVveB2wta1QiIjNldO1UkdqmulxEapda0KWGTCVB/wBh17NPRK9/DHylbBGJiMwki+mOu9QD1eUiUrs06avUkKksszYCfD56iIjUliCuO+5S81SXi0hN0yzuUkOOm6Cb2Q4mWI/U3U8pS0QiIjMpiClBl5qnulxEatrYLO6a9FWq31S6uG8seZ4G3gnMK084IiIzzAKNQZd6oLpcRGqXWtClhhxzmbVR7n6w5LHL3f8aeHX5QxMRmQFBXBW61DzV5SJS00wJutSOqXRxP7/kZUB4F76lbBGJiMwkdXGXOqC6XERqmmZxlxoylS7uf1nyPA/sAN5VnnBERGaYllmT+qC6XERq11gXd9XnUv2mkqB/yN2fLd1gZqvLFI+IyMwytaBLXVBdLiK1S2PQpYYcdww68O0pbhMRqT7q4i71QXW5iNSusVncVZ9L9TtmC7qZnQmsA9rM7O0lb7USzgArIlL9gpjuuEvNUl0uInVBk8RJDZmsi/sZwJuAOcCbS7b3A79ZxphERGaOxXTHXWqZ6nIRqX1jk8QpQZfqd8wE3d1vAW4xs5e7+70zGJOIyMwJ4uriLjVLdbmI1IWxBL1Y2ThEpsFkXdw/7e5/DrzHzN595Pvu/vGyRiYiMhOCQAm61CzV5SJSF4JoWi21oEsNmKyL+9bo54MzEYiISEUEcVXoUstUl4tI7dMkcVJDJuvi/r3o5z/PXDgiIjNMY9ClhqkuF5G6oDHoUkMm6+L+PcCP9b67v6UsEYmIzCSNQZcaprpcROqCZnGXGjJZF/e/mLEoREQqReugS21TXS4itU+TxEkNmayL+49Gn5tZEjiT8C78U+6enYHYRETKL4hBIVfpKETKQnW5iNSFQC3oUjsma0EHwMzeCPwd8AxgwGoz+y13v73cwYmIlJ3FoDhc6ShEykp1uYjUNCXoUkOOm6ADfwlc5u7bAczsVOAHgCp1Eal+6uIu9UF1uYjULs3iLjUkmMI++0Yr9MizwL4yxSMiMrO0zJrUB9XlIlK7NIu71JCptKBvNrPbgJsIx629E/iFmb0dwN2/U8b4RETKy2LgmlRGap7qchGpXWOzuKsFXarfVBL0NPAicGn0ej8wD3gzYSWvSl1Eqpe6uEt9UF0uIrUrUIIuteO4Cbq7f2AmAhERqYggpi5xUvNUl4tITdMkcVJDpjKL+2rgd4BVpfu7+1vKF5aIyAwJ4ppURmqe6nIRqWkagy41ZCpd3L8L/APwPUADNUWktpha0KUufBfV5SJSqzSLu9SQqSToI+7+xbJHIiJSCUEcispXpOapLheR2qVJ4qSGTCVB/4KZ/RHwQyAzutHdHy5bVCIiMyUI1IIu9UB1uYjUriAATAm61ISpJOhnA78GvJrxbnEevRYRqW4WU5c4qQeqy0WktgVx3XCXmjCVBP1twCnuni13MKPM7HeAjwF54Afu/ulo+2eBDwEF4OPufme0fQPwNaABuA34hLv7TMUrIlVMFbrUhxmvy0VEZpRWZZEaEUxhn0eBOWWOY4yZXQZcBZzj7uuAv4i2rwWuBtYBVwJfNhsdcMJXgGuBNdHjypmKV0SqXBDTGHSpBzNal4uIzLggDq76XKrfVFrQO4AnzewXjI9bc3e/qkwxfQT4U3fPRBfaF22/CvhmtH2HmW0HLjSz54BWd78XwMxuBN4K3F6m+ESklmiZNakPM12Xi4jMLLWgS42YSoL+RyXPDXgl8O7yhAPA6cCrzOx6YAT4PXf/BbAUuK9kv65oWy56fuR2EZHjM00SJ3VhputyEZGZpWVTpUYcN0F39x+Z2bnAe4B3ATuAv3spFzWzu4FFE7x1XRTTXOBi4ALgJjM7hfALxVHhTbJ9outeS9gVno6ODjo7O0849mMZGBiY1vNVK5VDSOUQqoZyWN21m+WFPD8uY5zVUA4zQeUQqkQ5lKMuFxGZVYK4ZnGXmnDMBN3MTicc8/1u4CDwLcDc/bKXelF3f80k1/0I8J1okrcHzKwIzCdsGV9esusyYHe0fdkE2ye67g3ADQAbN270TZs2vYRPcbjOzk6m83zVSuUQUjmEqqIcij+FnYWyxlkV5TADVA6hmSyHctblIiKziiZ9lRox2SRxTwKXA29291e6+98Qzp5ebt8lWvYl+mKRBA4AtwJXm1nKzFYTTgb3gLvvAfrN7GIzM+Aa4JYZiFNEaoHFANdEcVKrKlWXi4jMrCCmFnSpCZMl6P8F2Av8p5n9XzO7nIm7k0+3fwROMbMngG8C7/fQZuAmYAtwB/BR97GZnT4CfBXYDjyDJogTkakKoo5EmihOalOl6nIRkZkVxFSXS004Zhd3d78ZuNnMmghnRf9doMPMvgLc7O4/LEdA0Rqt7zvGe9cD10+w/UFgfTniEZEaF0T3KYsFiCUqG4vINKtUXS4iMuPUxV1qxHHXQXf3QXf/uru/iXB89yPAZ8odmIjIjBhtQVelLjVMdbmI1DzN4i414rgJeil3P+Tuf+/ury5XQCIiM8pi4U91i5M6MRN1uZn9jpk9ZWabzezPS7Z/1sy2R+9dUbJ9g5k9Hr33xWhOGRGRqdMs7lIjprIOuohI7RprQVelLjIdzOwy4CrgHHfPmNnCaPtawhnl1wFLgLvN7PRoPpmvEC6Deh9wG3Almk9GRE5EEKgul5pwQi3oIiI1J4ha0FWpi0yXjwB/6u4ZAHffF22/Cvimu2fcfQfhxK4XmtlioNXd742WWL2RcLy8iMjUaQy61Agl6CJS3wJ1cReZZqcDrzKz+83sR2Z2QbR9KfBCyX5d0bal0fMjt4uITF0QV10uNUFd3EWkvo2OQdddd5EpM7O7gUUTvHUd4XeLucDFwAXATWZ2ChMv7+aTbD/Wta8l7A5PR0cHnZ2dJxT7sQwMDEzbuaqZyiGkchhXLWVxXt8AxSDDo2WKtVrKodxUDqFyloMSdBGpb+riLnLC3P01x3rPzD4CfCfqrv6AmRWB+YQt48tLdl0G7I62L5tg+7GufQNwA8DGjRt906ZNJ/kpDtfZ2cl0nauaqRxCKodxVVMWO9oByhZr1ZRDmakcQuUsB3VxF5H6pmXWRKbbd4FXA5jZ6UASOADcClxtZikzWw2sAR5w9z1Av5ldHM3efg1wS0UiF5HqFWiZNakNakEXkfo2tsxasbJxiNSOfwT+0cyeALLA+6PW9M1mdhOwBcgDH41mcIdwYrmvAQ2Es7drBncROTFK0KVGKEEXkfqmLu4i08rds8D7jvHe9cD1E2x/EFhf5tBEpJZpkjipEeriLiL1LdAkcSIiIlVPy6xJjVCCLiL1bXQMuu66i4iIVC8L1BtOaoISdBGpb1pmTUREpPoFcSXoUhOUoItIfRubxV2TxImIiFQtdXGXGqEEXUTqWxD9N6hKXUREpHppFnepEUrQRaS+jS2zpm5xIiIiVSuIa8lUqQlK0EWkvo11cddddxERkaqlFnSpEUrQRaS+aR10ERGR6mdK0KU2KEEXkfo2tsyausWJiIhULc3iLjVCCbqI1DfTJHEiIiJVL4gpQZeaoARdROrb2Bh0VeoiIiJVK4hrwlepCUrQRaS+jY1BVwu6iIhI1dIkcVIjlKCLSH0bG4Ouu+4iIiJVS5PESY1Qgi4i9c00i7uIiEjV0yRxUiOUoItIfQtGJ4lTpS4iIlK1gjjgUNSqLFLdlKCLSH0LEuHPYq6ycYiIiMjJC7Qqi9QGJegiUt/iqfBnPlPZOEREROTkaU4ZqRFK0EWkvsWS4c9CtrJxiIiIyMkbWzZVLehS3ZSgi0h9Uwu6iIhI9TMtmyq1QQm6iNQ3taCLiIhUv7EWdE0SJ9VNCbqI1LcgFt51Vwu6iIhI9QrUgi61QQm6iEg8pRZ0ERGRaqYEXWqEEnQRkVhSCbqIiEg10yzuUiOUoIuIxFPq4i4iIlLNNIu71Agl6CIiMXVxFxERqWpjs7irBV2qmxJ0EZF4Ui3oIiIi1SxQgi61QQm6iIha0EVERKqbJomTGqEEXUQkllCCLiIiUs00SZzUCCXoIiKaJE5ERKS6aZI4qRFK0EVEtMyaiIhIddMkcVIjZl2Cbmbnmtl9ZvaImT1oZheWvPdZM9tuZk+Z2RUl2zeY2ePRe180M6tM9CJSldSCLiIiUt00SZzUiFmXoAN/Dvyxu58L/GH0GjNbC1wNrAOuBL5sNnqrjK8A1wJroseVMxyziFQzTRInIiJS3dTFXWrEbEzQHWiNnrcBu6PnVwHfdPeMu+8AtgMXmtlioNXd73V3B24E3jrDMYtINdMyayIiItVNs7hLjYhXOoAJfBK408z+gvAGwiXR9qXAfSX7dUXbctHzI7cfxcyuJWxpp6Ojg87OzmkLemBgYFrPV61UDiGVQ6hayuHMA920DfZxf5lirZZyKDeVQ0jlICJSBprFXWpERRJ0M7sbWDTBW9cBlwO/6+7/bmbvAv4BeA0w0bhyn2T70RvdbwBuANi4caNv2rTpxIM/hs7OTqbzfNVK5RBSOYSqphx6vw1DT5Ut1qophzJTOYRUDiIiZaAx6FIjKpKgu/trjvWemd0IfCJ6+W/AV6PnXcDykl2XEXZ/74qeH7ldRGRqNEmciIhIdTN1cZfaMBvHoO8GLo2evxrYFj2/FbjazFJmtppwMrgH3H0P0G9mF0ezt18D3DLTQYtIFdMkcSIiItVtbJI4taBLdZuNY9B/E/iCmcWBEaIx4+6+2cxuArYAeeCj7mODTD4CfA1oAG6PHiIiU6NJ4kRERKqbZnGXGjHrEnR3/ymw4RjvXQ9cP8H2B4H1ZQ5NRGpVLAXFHBSLEMzGjkUiIiIyKY1Blxqhb6IiIrFE+FPd3EVERKrTaIKuWdylyilBFxGJp8KfStBFRESqkyaJkxqhBF1EJKYEXWS6mNm5ZnafmT1iZg+a2YUl733WzLab2VNmdkXJ9g1m9nj03hejSV9FRKZOY9ClRihBFxGJJ8OfmihOZDr8OfDH7n4u8IfRa8xsLXA1sA64Eviy2WiTF18hnBR2TfS4coZjFpFqp1ncpUYoQRcRGWtBV4IuMg0caI2etxEunwpwFfBNd8+4+w5gO3ChmS0GWt39Xnd34EbgrTMcs4hUO00SJzVi1s3iLiIy48Za0NXFXWQafBK408z+grAh4JJo+1LgvpL9uqJtuej5kdsnZGbXEi3B2tHRQWdn57QEPTAwMG3nqmYqh5DKYVy1lEU8N8ArgW3bnmLXcOe0n79ayqHcVA6hcpaDEnQREbWgi5wQM7sbWDTBW9cBlwO/6+7/bmbvAv4BeA0w0bhyn2T7hNz9BuAGgI0bN/qmTZtOLPhj6OzsZLrOVc1UDiGVw7iqKYtMP/wM1pyyijWXbJr201dNOZSZyiFUznJQgi4iEota0Au5ysYhUiXc/TXHes/MbgQ+Eb38N+Cr0fMuYHnJrssIu793Rc+P3C4iMnWaxV1qhMagi4hokjiR6bQbuDR6/mpgW/T8VuBqM0uZ2WrCyeAecPc9QL+ZXRzN3n4NcMtMBy0iVU6TxEmNUAu6iIi6uItMp98EvmBmcWCEaLy4u282s5uALUAe+Ki7j36T/gjwNaABuD16iIhMnRJ0qRFK0EVENEmcyLRx958CG47x3vXA9RNsfxBYX+bQRKSWBVHHYHVxlyqnLu4iImpBFxERqX5BHFwt6FLdlKCLiMSjBF0t6CIiItUriKsFXaqeEnQRkVgi/FlQgi4iIlK1LKYx6FL1lKCLiKiLu4iISPUL4krQpeopQRcRURd3ERGR6hfE1MVdqp4SdBGRWDSLu1rQRUREqpcSdKkBStBFRNSCLiIiUv00i7vUACXoIiJBHDC1oIuIiFQzTRInNUAJuoiIWdjNPa8EXUREpGoFStCl+ilBFxGBsJt7IVfpKERERORkaR10qQFK0EVEIGxBVxd3ERGR6qVJ4qQGKEEXEYGwBV2TxImIiFQvTRInNUAJuogIqAVdRESk2mkMutQAJegiIhC1oCtBFxERqVqmLu5S/ZSgi4gAxBJQUBd3ERGRqhXE1YIuVU8JuogIQCylBF1ERKSaaRZ3qQFK0EVEQJPEiYiIVDuNQZcaoARdRAQ0SZyIiEi1C2KaxV2qnhJ0ERHQJHEiIiLVTl3cpQYoQRcRgagFXV3cRUREqpZmcZcaoARdRAQOb0Hf9RAc2FbZeEREROTEaBZ3qQFK0EVEIGpBz4XPv/vbcMvHKhuPiIiInBhNEic1QAm6iAgcPklc3x7oegCGuysbk4iIiExdoC7uUv2UoIuIwPgya/kMZHrBi/DMf1Y6KhEREZmqIK5Z3KXqKUEXEYHxFvTB/ePbtt99+D6FHLzwi5mNS0RERKZGk8RJDVCCLiIC45PEDewLX6fbYNtdUCyO7/OzL8A/vAaev7cyMYqIiMixBfHD622RKqQEXUQEIJYCHPr3hK/XvwMG98Hex8LX+Qw8cEP4/N4vVSREERERmYTGoEsNUIIuIgIQS4Q/e3eFP899T/hz+13hzye+AwMvwvKL4ckfwKEdMx+jiIiIHJsSdKkBStBFRCDs4g7Q+0L4c+FZsPhc+OW/wv6n4L6/hQVnwjv/KexCd//fVyxUERERmYAmiZMaUJEE3czeaWabzaxoZhuPeO+zZrbdzJ4ysytKtm8ws8ej975oZhZtT5nZt6Lt95vZqhn+OCJSC2LJ8GffLkg0QbIJXvvHMNIHX7kE9j4OF/82tC6B9W+HX/4L7P4luFc2bhEREQkFcbWgS9WLV+i6TwBvBw5rgjKztcDVwDpgCXC3mZ3u7gXgK8C1wH3AbcCVwO3Ah4Budz/NzK4G/gz41Zn6ICJSI8Za0HdB84Lw+Smb4KP3ww/+KxzYBue8K9z+ik/A1u/BDZtg7mpoXRpuX34hXPRb0LLosFPH8oOwb2s4AZ0XwQyaFkLTAnj+Z+G5glh4/PKLYOHa8HX/Xjj0LDR3hDcGEg1Hx10shC38XQ+Md88v/UyLz4VlG6FhTritkIMXn4DhnvB1c0fYMyCY4v3aYiH8LC/cD5k+aF0GTe2ATX5cw1wS2d7whoZNsm9uJLxJ0r8njNWLcODp8HoD0Qz7TfPhrDfD6l+BoYPj5RrEYMFZ47+/0Vi7HgjLqLcr3LZsAyy7EJZugFTz+LXdwzkH9j8dxmAW/m4b54WfL9kMi9aHv4eR3nCywC23wLY7Yd6p4Y2btVeFv6tRhRzs+BE82wmv/Z+Tf3YREXlpLBb+Py9SxSqSoLv7VgA7+ovKVcA33T0D7DCz7cCFZvYc0Oru90bH3Qi8lTBBvwr4XHT8t4EvmZm5q1lLRE5AbDRB7zo8wWpeCL/6r4fv27EOfndzmFg/dTtk+sMl2n76efj538Cis8ECyA5A7y5ele2Hn05y7cb54f6PfSt8nWyG9Bzo6zpiv/YwtlgqTEiHDkDfHijmSnYq/X+15L/BhrlhMt79HORHDj9vqi2MuW0ppFrD5Hg06R07VREGD0D/7pNunXgFwP2p8DOMJr2jCpnwswwdmPjg1mUwd2V4zM57Yct3j32hOSsBh76SWJMt4edzh6dvD7dZAAvXwbxV0DAvTKS7n5v8QwQJaFsW7edh2a15bXgD4I7PwB2fhRUvh/lrwuvvfji8iZBsgQuvhTkrjldMIiJysgIl6FL9KtWCfixLCVvIR3VF23LR8yO3jx7zAoC7582sF2gHjvqWZ2bXErbC09HRQWdn57QFPjAwMK3nq1Yqh5DKIVRN5TB//zbWA963mwPJpWyeUtwrYcmHx16ll+5hWdcPaBzqAgoUYm1kFpxKn7VCyxKyybm4xYAiqcwhktluBppX09u2DreA9Mg+Wvu20tb7JPH8AP0LrmCocRmJXA+pzAHSIwdIZg8RZMKkM5dcRWbpRgabltPXeibDDYsPa6GN5Ydo6d9Oa9/TpDL7SWW6GV70OvpazySbnAs46ZEXaet9kqbunaT2Pk2sMEg2Oa8k1nG51GpG2i5gqHEFvW1nkku0ksocJJHrP045OYlcH/TtopV+0iMHiA8NHr6Hpci0nU9m4XwyqflkUu0Ug3DYwUh6IZn0/PGdVxVo691KS/8zZJNzx2I1z9HS/ywt/dtwizOy7AKGGpfT23YWI+mOsbKJ5wZo7Xua1r6ttPRvJ/38L0lme+hvWcO+M95MX+sZZFLtUfkcIJ4PY43n+2nte4rGod0MrLqYvtYz6ZmzDg8SMB8aVnaxcN/PWLD/ZyT3bCaTms9gy9nsP+USuueeR/GRZ4Fnq+rfhYhIVTmyi3shD7f9Hlz4m+HNdZEqULYE3czuBhZN8NZ17n7LsQ6bYJtPsn2yY47e6H4DcAPAxo0bfdOmTccI48R1dnYyneerViqHkMohVFXl8NQwbAajyIKVZ72EuN991JaTLYeOk4zgpUoATWU4b2dnJ+un7e/h8mk6z7h50WMqFhzznfeNPUsCLRxdEVbVvwsRkWpy5CzuB56Gh/4pHOalBF2qRNkSdHd/zUkc1gUsL3m9DNgdbV82wfbSY7rMLA60AYdO4toiUs9GJ4mDcHy4iIiIVJcgDjgUi+HcKvu2hNtf3FLRsEROxGxbZu1W4OpoZvbVwBrgAXffA/Sb2cXR7O3XALeUHPP+6Pk7gHs0/lxETtjoJHEQjjsXERGR6hJEQ7NGl1rbt/XwnyJVoFLLrL3NzLqAlwM/MLM7Adx9M3ATsAW4A/hoNIM7wEeArwLbgWcIJ4gD+AegPZpQ7r8Cn5mxDyIitSNWkqA3zT/2fiIiIjI7jc6dMtrNff+T4c/eneGyqSJVoFKzuN8M3HyM964Hrp9g+4PA+gm2jwDvnO4YRaTOxNXFXUREpKoFUWozOpP7vi3h6iSZvrAVfcVFsPeJMIFfcm7FwhSZzGzr4i4iUhkxdXEXERGpamMJeh6yQ3BoB5z15nDbvs3hUpvfei/831fDz74YvhaZZZSgi4jAES3o6uIuIiJSdUbHoBcLcOApwGHN6yDZHLag79sK3c/BnBVw1/8Ht3y0ktGKTEgJuogIjM/iHktCek5FQxEREZGTUDpJ3OjEcB3rYOFZ4UzuT/0g3PbBO+AVn4RHvg7b7qpIqCLHogRdRATGu7g3LQCzysYiUgXM7J1mttnMima28Yj3Pmtm283sKTO7omT7BjN7PHrvi9HKLESrt3wr2n6/ma2a4Y8jIrWgdJK4fVvDun3uali4Nuzi/uRtsHQjtCyCy66D9tPgjs9CIVfZuEVKKEEXEYHxLu7q3i4yVU8Abwd+XLrRzNYCVwPrgCuBL5uNfmvmK8C1hMuoroneB/gQ0O3upwGfB/6s7NGLSO2JJcKfA/vCBH3B6RCLh63ow92w+2E44/XhPvEkXPEncHAbPHDD4ecpFiE7CEOHIJ85+jrFAgzsh7490LsLenaGXed7d8HggYnHtrtDbgTyWSjkw2tMNgY+nw3H0B/aAbnhkyqOwz5PPgOZgbAchg4dfVOikIf+vdDzQvhz6BBk+sPZ73t2hj0QDu0gke07PO5iIfxcuZHwOidjtDxmC/cwnkIuLLcZnqugIrO4i4jMOmMt6JogTmQq3H0rgB3d4+Qq4JvungF2RMugXmhmzwGt7n5vdNyNwFsJl029CvhcdPy3gS+ZmblrBicROQGnvhoa5sJ3fxuGDsIpl4bbF541vs+Zbxx/fvrr4LTXwp1/AHf9IcQboJCBQvbw8yZbuChogm3LwmT54Laj9ymVaoNF6yGeDhP9wX1h8l6YINnHwIKwe77Fxp9n+oGS/wIb5kLLYki1hDcBRnrC8ycawYtQzEWJbi5MLIv56GcufH8iiabwBoYTznTP8f/LfQXAQ23QfgqM9IbJ++iydolGmL8m7I043BN+drPwcwVB+NnyWcgNheWYGw6fF3PhZ2lfE84PEMTGywOimwoHYPBg+HtNpKG5A5JN4fvZobCMR/rCoYqxePQzGd60meh5bii8kTPSG95k8ML4zyPLK9UK81bDGW+ETb9/3DJ6qZSgi4jA+Bh0zeAu8lItBe4red0VbctFz4/cPnrMCwDunjezXqAdOHDkyc3sWsJWeDo6Oujs7JyWoAcGBqbtXNVM5RBSOYyrtrKYu+YTnPPYH2M4zwykeKGzk0S2j1cAw+lF3L95L2x5cWz/xMJrWFRcTDw/RFDM4JagGCQpxJIUgyTx/DCJXC82fIiGoSGKQSNDS95IJrWAYhADAtzCTsnmRYJihsahLpq7n8O8SCGWJpdYwsiSl5GPNwOOuQPFkp/hI3wvfJ5LNJNJzQeMZPYgqcwhUplDxPqHyCUWk5tzOkExS6wwglvssEcxiEfP40e8Ht1mxPNDxPMD0XUhH28km5xDMUgRFHOYFzDPY+7kEi0UYmmCYpbi4EHmFA7SMLybfHwxw8vOoxBrDMsy10PTYBfxgefIx5spxOaAH/75ikEzxUQ7hXSKYpCiEEtF5TxE41AXqa4nSvYvjl0/l2gl13A6udZWgmKGZLabYDi8SVIMWsnOWUkh1hgdG8YfFPOY58PPU8gT5PKYjxAUBygGCbLp08g3N0XlMvp7DI54biSz3TQM72Hg2W3soBMo778LJegiIhDe2W2YC3NWVjoSkVnDzO4GFk3w1nXufsuxDptgm0+yfbJjjt7ofgNwA8DGjRt906ZNxwjjxHR2djJd56pmKoeQymFc9ZXFJlhQhP/4H5x6yVs59bRN4eZnz6HhrDez6dLLJjjmLcc9a/WVQ3l0dnaybobLoWFGr3Zs7cDot8Ry/j0oQRcRGfUb/xFOHCMiALj7a07isC5gecnrZcDuaPuyCbaXHtNlZnGgDTh0EtcWEYFX/lc45TJYct74tg//ROueS1XQJHEiIqPaTx0fzyQiJ+tW4OpoZvbVhJPBPeDue4B+M7s4mr39GuCWkmPeHz1/B3CPxp+LyEkzg6XnH70qi1ZpkSqgFnQRERE5YWb2NuBvgAXAD8zsEXe/wt03m9lNwBYgD3zU3QvRYR8BvkbYY/H26AHwD8C/RBPKHSKcBV5ERKTuKEEXERGRE+buNwM3H+O964HrJ9j+ILB+gu0jwDunO0YREZFqoy7uIiIiIiIiIrOAEnQRERERERGRWUAJuoiIiIiIiMgsoARdREREREREZBZQgi4iIiIiIiIyCyhBFxEREREREZkFlKCLiIiIiIiIzAJK0EVERERERERmASXoIiIiIiIiIrOAuXulY6gIM9sPPD+Np5wPHJjG81UrlUNI5RBSOYRUDiGVQ2g6ymGluy+YjmCq2TTX5fr7DKkcQiqHcSqLkMohpHIIla0ur9sEfbqZ2YPuvrHScVSayiGkcgipHEIqh5DKIaRymJ30ewmpHEIqh3Eqi5DKIaRyCJWzHNTFXURERERERGQWUIIuIiIiIiIiMgsoQZ8+N1Q6gFlC5RBSOYRUDiGVQ0jlEFI5zE76vYRUDiGVwziVRUjlEFI5hMpWDhqDLiIiIiIiIjILqAVdREREREREZBZQgi4iIiIiIiIyCyhBPwFmdqWZPWVm283sMxO8b2b2xej9x8zs/ErEWW5TKIczzexeM8uY2e9VIsaZMoWyeG/0t/CYmf3czF5WiTjLbQrlcFVUBo+Y2YNm9spKxFluxyuHkv0uMLOCmb1jJuObKVP4e9hkZr3R38MjZvaHlYiz3Kby9xCVxSNmttnMfjTTMdYj1eUh1eUh1eMh1eMh1eMh1eOhitXj7q7HFB5ADHgGOAVIAo8Ca4/Y5w3A7YABFwP3VzruCpXDQuAC4Hrg9yodc4XL4hJgbvT89XX8N9HM+JwX5wBPVjruSpRDyX73ALcB76h03BX6e9gEfL/Ssc6CcpgDbAFWRK8XVjruWn+oLj+hcqj5ulz1+AmVg+rxw/dTPa56vGz1uFrQp+5CYLu7P+vuWeCbwFVH7HMVcKOH7gPmmNnimQ60zI5bDu6+z91/AeQqEeAMmkpZ/Nzdu6OX9wHLZjjGmTCVchjw6H8uoAmoxdkpp/J/BMDvAP8O7JvJ4GbQVMuh1k2lHN4DfMfdd0L4f+cMx1iPVJeHVJeHVI+HVI+HVI+HVI+HKlaPK0GfuqXACyWvu6JtJ7pPtauHzzhVJ1oWHyJslak1UyoHM3ubmT0J/AD44AzFNpOOWw5mthR4G/B3MxjXTJvqv4uXm9mjZna7ma2bmdBm1FTK4XRgrpl1mtlDZnbNjEVXv1SXh+rhM06F6vGQ6vGQ6vGQ6vFQxerx+HScpE7YBNuOvHs4lX2qXT18xqmaclmY2WWEFXstjtmaUjm4+83AzWb2K8D/BF5T7sBm2FTK4a+B33f3gtlEu9eEqZTDw8BKdx8wszcA3wXWlDuwGTaVcogDG4DLgQbgXjO7z92fLndwdUx1eagePuNUqB4PqR4PqR4PqR4PVaweV4I+dV3A8pLXy4DdJ7FPtauHzzhVUyoLMzsH+Crwenc/OEOxzaQT+ptw9x+b2almNt/dD5Q9upkzlXLYCHwzqtTnA28ws7y7f3dGIpwZxy0Hd+8reX6bmX25Tv8euoAD7j4IDJrZj4GXAUrQy0d1eagePuNUqB4PqR4PqR4PqR4PVaweVxf3qfsFsMbMVptZErgauPWIfW4FrolmgL0Y6HX3PTMdaJlNpRzqxXHLwsxWAN8Bfq2GW8WmUg6nWVSbRTMiJ4Fa+5Jz3HJw99XuvsrdVwHfBn67xip1mNrfw6KSv4cLCeuiuvt7AG4BXmVmcTNrBC4Cts5wnPVGdXlIdXlI9XhI9XhI9XhI9XioYvW4WtCnyN3zZvYx4E7CWf3+0d03m9mHo/f/jnA2xzcA24Eh4AOVirdcplIOZrYIeBBoBYpm9knCWQ/7jnXeajTFv4k/BNqBL0f/j+XdfWOlYi6HKZbDfyH8wpsDhoFfLZlspiZMsRxq3hTL4R3AR8wsT/j3cHU9/j24+1YzuwN4DCgCX3X3JyoXde1TXR5SXR5SPR5SPR5SPR5SPR6qZD1uNVaWIiIiIiIiIlVJXdxFREREREREZgEl6CIiIiIiIiKzgBJ0ERERERERkVlACbqIiIiIiIjILKAEXURERERERGQWUIIuUqfMrN3MHokee81sV/R8wMy+XKZrftLMrjmJ45Jm9mMz09KQIiIiEdXlIrVHy6yJCGb2OWDA3f+ijNeIAw8D57t7/iSO/yNgu7t/fdqDExERqXKqy0Vqg1rQReQwZrbJzL4fPf+cmf2zmf3QzJ4zs7eb2Z+b2eNmdoeZJaL9NpjZj8zsITO708wWT3DqVwMPj1boZtZpZhuj5/PN7Lno+TozeyBqAXjMzNZEx38XeG95P72IiEj1U10uUr2UoIvI8ZwKvBG4CvhX4D/d/WxgGHhjVLH/DfAOd98A/CNw/QTneQXw0BSu92HgC+5+LrAR6Iq2PwFc8BI+h4iISL1SXS5SJTQGRESO53Z3z5nZ40AMuCPa/jiwCjgDWA/cZWZE++yZ4DyLga1TuN69wHVmtgz4jrtvA3D3gpllzazF3ftfygcSERGpM6rLRaqEEnQROZ4MgLsXzSzn4xNXFAn/DzFgs7u//DjnGQbSR2yz6GdidIO7f8PM7ie803+nmf2Gu98TvZ0CRk7+o4iIiNQl1eUiVUJd3EXkpXoKWGBmLwcws4SZrZtgv63AaUdsG+3mtonwbj1mdgrwrLt/EbgVOCfa3g7sd/fctH8CERGR+qa6XGSWUIIuIi+Ju2eBdwB/ZmaPAo8Al0yw6+3Arxyx7TVm9gvgNcAhM/s48KvAE2b2CHAmcGO072XAbdP+AUREROqc6nKR2UPLrInIjDGzm4FPu/s2M+sEfs/dH5zisd8BPuvuT5UzRhERETk21eUi5aUWdBGZSZ8hnGDmhJhZEviuKnQREZGKU10uUkZqQRcRERERERGZBdSCLiIiIiIiIjILKEEXERERERERmQWUoIuIiIiIiIjMAkrQRURERERERGYBJegiIiIiIiIis8D/DzuMoHX/GyxBAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
      " + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "def compare_modes():\n", + "\n", + " class BufferCompare(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"pulse\",\n", + " style=\"const\", freq=cfg['freq'],\n", + " length=cfg['pulse_len'], phase=0, gain=cfg['gain'])\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\",\n", + " freq=cfg['freq'], gen_ch=cfg['gen_ch'])\n", + "\n", + " def _body(self, cfg):\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", t=0)\n", + " self.pulse(ch=cfg['gen_ch'], name=\"pulse\", t=0)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'])\n", + "\n", + " common_config = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500.0,\n", + " 'pulse_len': 0.5,\n", + " 'gain': 0.5,\n", + " 'ro_len': 0.6,\n", + " 'trig_time': 0.05\n", + " }\n", + "\n", + " # Correct buffer and sample rate calculation\n", + " buf_maxlen = soccfg['readouts'][RO_CH]['buf_maxlen'] # 1024 for acquire_decimated\n", + " f_output = soccfg['readouts'][RO_CH]['f_output'] # decimated rate MHz\n", + " samples_per_rep = int(common_config['ro_len'] * f_output)\n", + " max_reps = max(1, buf_maxlen // samples_per_rep)\n", + " print(f\"f_output: {f_output} MHz\")\n", + " print(f\"Buffer: {buf_maxlen}, samples/rep: {samples_per_rep}, max_reps: {max_reps}\")\n", + "\n", + " # Single rep\n", + " prog_single = BufferCompare(soccfg, reps=1, final_delay=0.5, cfg=common_config)\n", + " iq_single = prog_single.acquire_decimated(soc, rounds=1, progress=False)\n", + "\n", + " # Max reps\n", + " prog_avg = BufferCompare(soccfg, reps=max_reps, final_delay=0.5, cfg=common_config)\n", + " iq_avg = prog_avg.acquire_decimated(soc, rounds=1, progress=False)\n", + "\n", + " # Normalize shapes — could be (reps, n_samples, 2) or (n_samples, 2)\n", + " def to_2d(data):\n", + " d = np.array(data)\n", + " if d.ndim == 3:\n", + " return d.mean(axis=0) # average over reps → (n_samples, 2)\n", + " return d # already (n_samples, 2)\n", + "\n", + " single = to_2d(iq_single[0]) # (n_samples, 2)\n", + " avg = to_2d(iq_avg[0]) # (n_samples, 2)\n", + "\n", + " print(f\"Single shape: {single.shape}, Avg shape: {avg.shape}\")\n", + "\n", + " time_single = prog_single.get_time_axis(ro_index=0)\n", + " time_avg = prog_avg.get_time_axis(ro_index=0)\n", + "\n", + " fig, axes = plt.subplots(1, 2, figsize=(14, 5))\n", + "\n", + " axes[0].plot(time_single, single[:, 0], label='I')\n", + " axes[0].plot(time_single, single[:, 1], label='Q')\n", + " axes[0].set_xlabel('Time (µs)')\n", + " axes[0].set_ylabel('Amplitude')\n", + " axes[0].set_title('Single shot (reps=1)')\n", + " axes[0].legend()\n", + " axes[0].grid(True)\n", + "\n", + " axes[1].plot(time_avg, avg[:, 0], label='I')\n", + " axes[1].plot(time_avg, avg[:, 1], label='Q')\n", + " axes[1].set_xlabel('Time (µs)')\n", + " axes[1].set_ylabel('Amplitude')\n", + " axes[1].set_title(f'Averaged (reps={max_reps})')\n", + " axes[1].legend()\n", + " axes[1].grid(True)\n", + "\n", + " plt.tight_layout()\n", + " plt.show()\n", + "\n", + " return single, avg\n", + "\n", + "single_data, avg_data = compare_modes()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 7. Practical Application: Power Monitoring from Buffered Acquisition\n", + "\n", + "Decimated readout data can be analyzed to estimate signal power and detect threshold crossings. \n", + "This example demonstrates how to compute instantaneous power from IQ samples and identify events of interest." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc pmem: loading data\n", + "INFO [tproc.py:695] tProc pmem: readback OK\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Decimated rate: 307.2 MHz\n", + "Samples per rep: 614\n", + "Buffer max: 1024 samples\n", + "Max reps: 1\n", + "Using reps=1, rounds=100 (100 total shots)\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:662] tProc wmem: loading data\n", + "INFO [tproc.py:695] tProc wmem: readback OK\n", + "INFO [tproc.py:524] PROCESSOR_RESET\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n", + "INFO [tproc.py:512] PROCESSOR_START\n", + "INFO [tproc.py:515] PROCESSOR_STOP\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Raw data shape: (614, 2)\n" + ] + }, + { + "data": { + "image/png": "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sccey7Rp01i7dm2rz1dqsLaHu/8nsCbuGXossH+rzy6yFdxVIyIipVu9ejVPP/00N998cz5Ye/DBB/n617+e36a2tpbjj48m6XnooYc45JBDGDVqFCeffDKrV68GYPDgwfzoRz/isMMO4+677+amm26iurqaESNGcNJJJ+W/jP/xj39w8MEHU11dzRVXXLFZac3Pf/5zqqurGT58+GalLRMmTGDvvffmC1/4Am+++WbRfJx11llccMEFjB07lqFDh/L3v/+ds88+m8985jOcddZZ+e0uuOACRo8ezbBhwzY7xwMPPMA+++zDYYcdxve+9z2OO+44ICrJO/vss6mpqWHo0KFMnDgxv08u7ePHj+fJJ59k5MiRXH/99VuUmB133HHU1tYC8Pvf/5699tqLz33uczz99KbRvT766CNOOukkqqurqa6u3mxdzqpVq3j11VcZMWIEAP369aO6unqLHpPTp09njz32YOjQoXTp0oVx48Zx7733AnDvvfdy5plnAnDmmWdyzz33bHGeRYsWccQRRzBy5Ej2228/nnzyyfy6H/7wh4wYMYKDDz6YxYsXAzBv3jyOPPJIhg8fzvHHH8/777/PM888w7Rp07j00ksZOXIk//jHP5g4cSL77rsvw4cPZ9y4cUBUE1RTU8N9991X7LJulVJ7g9bFf5eb2X7Ah8DgVp9dZCu4Oxk1WhNJnf/6yyxmL1y5TfturM9Sn82yfZfNv6723WUHrjx+WLP73nPPPRxzzDHstdde9O7dm5kzZ3LUUUdx/vnns2bNGrp3784dd9zBKaecwscff8xPfvITHnnkEbp3787PfvYzrr32Wq644gogGm7hqaeeYtWqVWzcuJFzzz0XgMsvv5ybb76Z7373u1x88cVcfPHFnHrqqfzmN7/Jp+Ohhx7i7bffZvr06bg7J5xwAk888QTdu3dn6tSpvPTSS9TX1zNq1CgOPPDAonlZtmwZjz32GNOmTeP444/n6aef5ne/+x3V1dW8/PLLjBw5kgkTJtC7d28aGho48sgjefXVV9lrr704//zzeeKJJxgyZAinnnrqZsedM2cOjz/+OKtWrWLvvffmggsu2CxAuvrqq/nFL37Bfffdx6pVq/jTn/5UNH2LFi3iyiuvZMaMGey4446MHTuWAw44AICLL76YSy65hMMOO4z333+fo48+eoshMF588UX226/liZE++OADBg0alH89cOBAnn/+eQAWL17MgAEDABgwYABLlizZYv/bb7+do48+mh/+8Ic0NDTkA+01a9Zw8MEHM2HCBP793/+dm266icsvv5yLLrqIM844gzPPPJMbbriB733ve9xzzz2ccMIJHHfccXzta1/Lv0/vvfceXbt2Zfny5fnzjR49mieffHKzHwjbotSStRvNbCfgcmAaMBv4WavOLLKVsipZE5GtMGXKlHwpx7hx45gyZQqVlZUcc8wx/OUvf6G+vp7777+fE088keeee47Zs2dz6KGHMnLkSCZPnsy8efPyxzrllFPyz19//XUOP/xw9t9/f/7whz8wa9YsAJ599llOPvlkAL7xjW/kt3/ooYd46KGHOOCAAxg1ahRz5szh7bff5sknn+SrX/0q22+/PTvssAMnnHBCk3k5/vjjMTP2339/+vfvz/77708mk2HYsGHMnTsXgDvvvJNRo0ZxwAEHMGvWLGbPns2cOXMYOnRofpiIxsHascceS9euXenbty/9+vXLlyhtreeff56amhp23nlnunTpstn79cgjj3DRRRcxcuRITjjhBFauXMmqVZu3pFq0aBE777xzi+fxIrNZbE1b5urqan7/+99z1VVX8dprr+WH4ujSpUu+xPHAAw/Mv6fPPvts/lqOGzeOp556quhxhw8fzmmnncZtt91GZeWmHxb9+vVj4cKFJaevKaUOivu7+OkTwNBWn1VkGziabkokjVoqAWvOwuXrWLZ2I8N22XGr9lu6dCmPPfYYr7/+OmZGQ0MDZsY111zDKaecwq9//Wt69+5NdXU1PXv2xN056qijmDJlStHjde/ePf/8rLPO4p577mHEiBFMmjQpXw3YFHfnsssu4/zzz99s+XXXXVdyoNG1a1cAMplM/nnudX19Pe+99x6/+MUveOGFF9hpp50466yzWL9+fdHgpthxASoqKqivr292+8rKSrIFU0oUDkHRVF6y2SzPPvss2223XZPH3W677UoazmLgwIHMnz8//3rBggXssssuAPTv359FixYxYMAAFi1aRL9+/bbY/4gjjuCJJ57g/vvv5/TTT+fSSy/ljDPOoKqqKp/+5t6HpvJ4//3388QTTzBt2jR+/OMfM2vWLCorK1m/fn2z+S5VsyVrZvZNM2tyGzP7tJkd1upUiJRAvUFFArUNHQzuuusuzjjj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\n", + "text/plain": [ + "
      " + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Data shape: (614, 2)\n", + "Time range: 0.000 – 1.995 µs\n", + "Mean magnitude: 507.3328\n", + "Peak magnitude: 1039.8059\n" + ] + } + ], + "source": [ + "class AveragingProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + " \n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"test_pulse\",\n", + " style=\"const\",\n", + " freq=cfg['freq'], length=cfg['pulse_len'],\n", + " phase=0, gain=cfg['gain'])\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\",\n", + " freq=cfg['freq'], gen_ch=cfg['gen_ch'])\n", + "\n", + " def _body(self, cfg):\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", t=0) # moved here\n", + " self.pulse(ch=cfg['gen_ch'], name=\"test_pulse\", t=0)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'])\n", + "\n", + "config_avg = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 500.0,\n", + " 'pulse_len': 1.0,\n", + " 'gain': 0.5,\n", + " 'trig_time': 0.05,\n", + " 'ro_len': 2.0,\n", + " 'avg_rounds': 100\n", + "}\n", + "\n", + "buf_maxlen = soccfg['readouts'][RO_CH]['buf_maxlen'] # samples\n", + "f_output = soccfg['readouts'][RO_CH]['f_output'] # MHz — decimated rate\n", + "samples_per_rep = int(config_avg['ro_len'] * f_output) # correct rate\n", + "\n", + "print(f\"Decimated rate: {f_output} MHz\")\n", + "print(f\"Samples per rep: {samples_per_rep}\")\n", + "print(f\"Buffer max: {buf_maxlen} samples\")\n", + "\n", + "if samples_per_rep > buf_maxlen:\n", + " # ro_len too long — clamp it\n", + " max_ro_len = buf_maxlen / f_output\n", + " print(f\"WARNING: ro_len={config_avg['ro_len']} µs too long, \"\n", + " f\"clamping to {max_ro_len:.3f} µs\")\n", + " config_avg['ro_len'] = max_ro_len\n", + " samples_per_rep = buf_maxlen\n", + "\n", + "max_reps = buf_maxlen // samples_per_rep\n", + "reps_per_round = max(1, min(config_avg['avg_rounds'], max_reps))\n", + "n_rounds = max(1, config_avg['avg_rounds'] // reps_per_round)\n", + "print(f\"Max reps: {max_reps}\")\n", + "print(f\"Using reps={reps_per_round}, rounds={n_rounds} \"\n", + " f\"({reps_per_round * n_rounds} total shots)\")\n", + "\n", + "prog = AveragingProgram(soccfg, reps=reps_per_round, final_delay=0.5, cfg=config_avg)\n", + "iq_avg = prog.acquire_decimated(soc, rounds=n_rounds, progress=False)\n", + "\n", + "data = np.array(iq_avg[0])\n", + "print(\"Raw data shape:\", data.shape)\n", + "\n", + "# Average over reps axis if present\n", + "if data.ndim == 3:\n", + " data = data.mean(axis=0) # (reps, n_samples, 2) → (n_samples, 2)\n", + "\n", + "magnitude = np.abs(data[:, 0] + 1j * data[:, 1])\n", + "time_axis = prog.get_time_axis(ro_index=0)\n", + "n = min(len(time_axis), len(magnitude))\n", + "\n", + "plt.figure(figsize=(10, 5))\n", + "plt.plot(time_axis[:n], magnitude[:n],\n", + " label=f'Averaged magnitude ({reps_per_round * n_rounds} shots)')\n", + "plt.xlabel('Time (µs)')\n", + "plt.ylabel('|IQ| (a.u.)')\n", + "plt.title(f'Averaging: {reps_per_round} reps × {n_rounds} rounds '\n", + " f'= {reps_per_round * n_rounds} total')\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.show()\n", + "\n", + "print(f\"Data shape: {data.shape}\")\n", + "print(f\"Time range: {time_axis[0]:.3f} – {time_axis[n-1]:.3f} µs\")\n", + "print(f\"Mean magnitude: {magnitude.mean():.4f}\")\n", + "print(f\"Peak magnitude: {magnitude.max():.4f}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 8. Summary\n", + "\n", + "You have learned:\n", + "\n", + "* How to acquire IQ data using buffered (decimated) readout\n", + "* How decimation reduces data rate while preserving signal information\n", + "* How on-FPGA averaging reduces noise without host involvement\n", + "* The trade-offs between buffered acquisition and streaming approaches\n", + "* How to estimate signal power and detect threshold crossings from IQ data\n", + "\n", + "**Key takeaways:**\n", + "\n", + "* Buffered acquisition (`acquire_decimated`) is simple and effective for most measurements\n", + "* Decimation allows you to balance data rate and temporal resolution\n", + "* On-FPGA averaging is efficient for repetitive measurements\n", + "* Streaming enables continuous acquisition but requires a different programming model\n", + "* Power monitoring can be implemented from IQ data, even without true real-time streaming\n", + "\n", + "**Next steps:** Proceed to [`12_DSP_Blocks_And_Correlators.ipynb`](./12_DSP_Blocks_And_Correlators.ipynb) to learn about advanced signal processing with DSP blocks and correlators." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/source/tutorials/12_DSP_Blocks_And_Correlators.ipynb b/docs/source/tutorials/12_DSP_Blocks_And_Correlators.ipynb new file mode 100644 index 000000000..aa2453644 --- /dev/null +++ b/docs/source/tutorials/12_DSP_Blocks_And_Correlators.ipynb @@ -0,0 +1,717 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 12 - DSP Blocks and Correlators\n", + "\n", + "**Objective:** Use FIR filters, DDS tuning, and hardware correlators for advanced signal processing. This notebook covers:\n", + "- Configuring and applying FIR filters\n", + "- Dynamic DDS frequency tuning during sequences\n", + "- Using hardware correlators for multi-channel measurements\n", + "- Generating multi-tone signals and performing spectrum analysis" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%pybind11/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ready\n" + ] + } + ], + "source": [ + "# Standard imports\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import logging\n", + "from scipy import signal\n", + "\n", + "from qick import *\n", + "from qick.asm_v2 import AveragerProgramV2\n", + "\n", + "# Setup logging\n", + "logging.basicConfig(level=logging.INFO, format='%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s')\n", + "\n", + "# Connect to the board\n", + "BITSTREAM_PATH = 'qick_216.bit'#'/path/to/your/firmware.bit' # <--- CHANGE THIS\n", + "soc = QickSoc(BITSTREAM_PATH)\n", + "soccfg = soc\n", + "\n", + "# Define hardware channels\n", + "GEN_CH = 0\n", + "RO_CH = 0\n", + "\n", + "print(\"Ready\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. FIR Filters Overview\n", + "\n", + "Finite Impulse Response (FIR) filters are implemented in the FPGA fabric for real-time signal processing. They can be used for:\n", + "- Pulse shaping (e.g., Gaussian, raised cosine)\n", + "- Band limiting and anti-aliasing\n", + "- Matched filtering for optimal SNR\n", + "- Removing unwanted frequency components" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Configuring an FIR Filter\n", + "\n", + "FIR filters are applied to DAC outputs. Let's design and apply a low-pass filter." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
      " + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Filter coefficients: [ 0 -159 -141 214 523 0 -1096 -942 1287 2819]...\n", + "Number of taps: 31\n" + ] + } + ], + "source": [ + "def design_lowpass_filter(cutoff_mhz, sample_rate_mhz=100, num_taps=31):\n", + " \"\"\"\n", + " Design a simple low-pass FIR filter.\n", + " \n", + " Parameters:\n", + " - cutoff_mhz: Cutoff frequency in MHz\n", + " - sample_rate_mhz: DAC sample rate in MHz (typically 100 for 1ns resolution)\n", + " - num_taps: Number of filter taps (must be odd, max 255 for QICK)\n", + " \"\"\"\n", + " # Normalized cutoff frequency (Nyquist = 0.5)\n", + " nyquist = sample_rate_mhz / 2\n", + " normalized_cutoff = cutoff_mhz / nyquist\n", + " \n", + " # Design filter using Kaiser window\n", + " taps = signal.firwin(num_taps, normalized_cutoff, window='hamming')\n", + " \n", + " # Scale to QICK's 16-bit integer representation\n", + " # QICK expects coefficients in Q1.15 format (range -32768 to 32767)\n", + " max_tap = np.max(np.abs(taps))\n", + " taps_scaled = (taps / max_tap * 32767).astype(int)\n", + " \n", + " return taps_scaled\n", + "\n", + "# Design a filter with 20 MHz cutoff\n", + "cutoff_freq = 20 # MHz\n", + "filter_taps = design_lowpass_filter(cutoff_freq, num_taps=31)\n", + "\n", + "# Visualize the filter response\n", + "freq_response = np.abs(np.fft.rfft(filter_taps, n=1024))\n", + "freqs = np.linspace(0, 50, len(freq_response))\n", + "\n", + "plt.figure(figsize=(12, 4))\n", + "plt.subplot(1, 2, 1)\n", + "plt.stem(filter_taps, basefmt=' ')\n", + "plt.xlabel('Tap Index')\n", + "plt.ylabel('Coefficient Value')\n", + "plt.title(f'FIR Filter Taps (31 taps, {cutoff_freq} MHz cutoff)')\n", + "plt.grid(True)\n", + "\n", + "plt.subplot(1, 2, 2)\n", + "plt.plot(freqs, 20 * np.log10(freq_response / np.max(freq_response) + 1e-10))\n", + "plt.axvline(x=cutoff_freq, color='r', linestyle='--', label=f'{cutoff_freq} MHz cutoff')\n", + "plt.xlabel('Frequency (MHz)')\n", + "plt.ylabel('Gain (dB)')\n", + "plt.title('Filter Frequency Response')\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.ylim(-80, 5)\n", + "plt.tight_layout()\n", + "plt.show()\n", + "\n", + "print(f\"Filter coefficients: {filter_taps[:10]}...\")\n", + "print(f\"Number of taps: {len(filter_taps)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "FIR filter configured for DAC channel.\n", + "The filter will shape the output pulse spectrum.\n", + "\n", + "Note: FIR filters are applied in real-time on the FPGA.\n", + "To see the effect, compare the pulse shape with and without the filter.\n" + ] + } + ], + "source": [ + "class FIRFilterProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + "\n", + " # Apply FIR filter to the generator channel\n", + " # The filter is applied to the baseband signal before IQ modulation\n", + " self.set_fir_filter(\n", + " ch=cfg['gen_ch'],\n", + " coeffs=cfg['filter_coeffs'],\n", + " gain=cfg.get('filter_gain', 1.0) # Optional gain compensation\n", + " )\n", + "\n", + " # Define a test pulse (square pulse to see filtering effect)\n", + " self.add_pulse(\n", + " ch=cfg['gen_ch'], name=\"test_pulse\",\n", + " style=\"const\",\n", + " freq=cfg['freq'], length=cfg['pulse_len'],\n", + " phase=0, gain=cfg['gain']\n", + " )\n", + "\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\",\n", + " freq=cfg['freq'], gen_ch=cfg['gen_ch'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", t=0)\n", + "\n", + " def _body(self, cfg):\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'], ddr4=True)\n", + " self.pulse(ch=cfg['gen_ch'], name=\"test_pulse\", t=0)\n", + "\n", + "# Configuration with filter\n", + "config_fir = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq': 100.0,\n", + " 'pulse_len': 0.5,\n", + " 'gain': 0.5,\n", + " 'trig_time': 0.05,\n", + " 'ro_len': 0.8,\n", + " 'filter_coeffs': filter_taps.tolist(),\n", + " 'filter_gain': 1.0\n", + "}\n", + "\n", + "print(\"FIR filter configured for DAC channel.\")\n", + "print(\"The filter will shape the output pulse spectrum.\")\n", + "print(\"\\nNote: FIR filters are applied in real-time on the FPGA.\")\n", + "print(\"To see the effect, compare the pulse shape with and without the filter.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Dynamic DDS Tuning\n", + "\n", + "The Direct Digital Synthesizer (DDS) generates the carrier frequency. You can change the DDS frequency mid-sequence, enabling frequency sweeps and multi-frequency experiments." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== Multi-Frequency Pulse Sequence ===\n", + "The sequence plays three pulses at different frequencies:\n", + " - 0.05 µs: 90.0 MHz\n", + " - 0.30 µs: 100.0 MHz\n", + " - 0.60 µs: 110.0 MHz\n", + "\n", + "Note: Each pulse has a fixed frequency defined at compile time.\n", + "This approach is useful for:\n", + " - Frequency-selective qubit control\n", + " - Multi-tone readout\n", + " - Off-resonant driving experiments\n" + ] + } + ], + "source": [ + "class DynamicDDSProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + "\n", + " # Crear UN pulso por frecuencia\n", + " self.add_pulse(\n", + " ch=cfg['gen_ch'],\n", + " name=\"pulse_f1\",\n", + " style=\"const\",\n", + " freq=cfg['freq1'],\n", + " length=0.1,\n", + " phase=0,\n", + " gain=cfg['gain']\n", + " )\n", + "\n", + " self.add_pulse(\n", + " ch=cfg['gen_ch'],\n", + " name=\"pulse_f2\",\n", + " style=\"const\",\n", + " freq=cfg['freq2'],\n", + " length=0.1,\n", + " phase=0,\n", + " gain=cfg['gain']\n", + " )\n", + "\n", + " self.add_pulse(\n", + " ch=cfg['gen_ch'],\n", + " name=\"pulse_f3\",\n", + " style=\"const\",\n", + " freq=cfg['freq3'],\n", + " length=0.1,\n", + " phase=0,\n", + " gain=cfg['gain']\n", + " )\n", + "\n", + " self.add_readoutconfig(\n", + " ch=cfg['ro_ch'],\n", + " name=\"my_ro\",\n", + " freq=cfg['freq2'], # frecuencia de referencia\n", + " gen_ch=cfg['gen_ch']\n", + " )\n", + "\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\", t=0)\n", + "\n", + " def _body(self, cfg):\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'], ddr4=True)\n", + "\n", + " # Ejecutar cada pulso con distinta frecuencia\n", + " self.pulse(ch=cfg['gen_ch'], name=\"pulse_f1\", t=0.05, tag='f1')\n", + " self.pulse(ch=cfg['gen_ch'], name=\"pulse_f2\", t=0.3, tag='f2')\n", + " self.pulse(ch=cfg['gen_ch'], name=\"pulse_f3\", t=0.6, tag='f3')\n", + "\n", + "\n", + "config_dds = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq1': 90.0,\n", + " 'freq2': 100.0,\n", + " 'freq3': 110.0,\n", + " 'gain': 0.5,\n", + " 'trig_time': 0.02,\n", + " 'ro_len': 0.9\n", + "}\n", + "\n", + "prog = DynamicDDSProgram(soccfg, reps=1, final_delay=0.5, cfg=config_dds)\n", + "print(\"=== Multi-Frequency Pulse Sequence ===\")\n", + "print(\"The sequence plays three pulses at different frequencies:\")\n", + "print(f\" - 0.05 µs: {config_dds['freq1']} MHz\")\n", + "print(f\" - 0.30 µs: {config_dds['freq2']} MHz\")\n", + "print(f\" - 0.60 µs: {config_dds['freq3']} MHz\")\n", + "\n", + "print(\"\\nNote: Each pulse has a fixed frequency defined at compile time.\")\n", + "print(\"This approach is useful for:\")\n", + "print(\" - Frequency-selective qubit control\")\n", + "print(\" - Multi-tone readout\")\n", + "print(\" - Off-resonant driving experiments\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Hardware Correlators\n", + "\n", + "The QICK includes hardware correlators that can compute cross-correlations between channels in real-time. This is useful for:\n", + "- Multi-qubit readout\n", + "- Noise correlation measurements\n", + "- Time-of-flight experiments\n", + "- Quantum state tomography" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hardware Correlator Configuration:\n", + "- Correlating ADC channels 0 and 1\n", + "- Correlation length: 100 samples\n", + "- Pulse delay: 0.1 µs\n", + "\n", + "The correlator computes: C[τ] = Σ I(t) * I(t+τ) + Q(t) * Q(t+τ)\n", + "This provides real-time cross-correlation between two channels.\n" + ] + } + ], + "source": [ + "class HardwareCorrelatorProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1)\n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + " \n", + " # Enable hardware correlator\n", + " # This correlates two ADC channels\n", + " self.enable_correlator(\n", + " ch0=cfg['corr_ch0'], # First ADC channel\n", + " ch1=cfg['corr_ch1'], # Second ADC channel\n", + " length=cfg['corr_len'] # Correlation length in samples\n", + " )\n", + "\n", + " # Define pulses on two generator channels\n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"pulse1\",\n", + " style=\"const\", freq=cfg['freq1'],\n", + " length=cfg['pulse_len'], phase=0, gain=cfg['gain'])\n", + " \n", + " self.add_pulse(ch=cfg['gen_ch2'], name=\"pulse2\",\n", + " style=\"const\", freq=cfg['freq2'],\n", + " length=cfg['pulse_len'], phase=0, gain=cfg['gain'])\n", + "\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"ro1\",\n", + " freq=cfg['freq1'], gen_ch=cfg['gen_ch'])\n", + " self.add_readoutconfig(ch=cfg['ro_ch2'], name=\"ro2\",\n", + " freq=cfg['freq2'], gen_ch=cfg['gen_ch2'])\n", + "\n", + " def _body(self, cfg):\n", + " self.pulse(ch=cfg['gen_ch'], name=\"pulse1\", t=0)\n", + " self.pulse(ch=cfg['gen_ch2'], name=\"pulse2\", t=cfg['delay'])\n", + " \n", + " self.trigger(ros=[cfg['ro_ch'], cfg['ro_ch2']], pins=[0, 1], t=cfg['trig_time'])\n", + "\n", + "config_corr = {\n", + " 'gen_ch': GEN_CH,\n", + " 'gen_ch2': 1,\n", + " 'ro_ch': RO_CH,\n", + " 'ro_ch2': 1,\n", + " 'freq1': 100.0,\n", + " 'freq2': 100.0,\n", + " 'pulse_len': 0.2,\n", + " 'delay': 0.1, # Delay between pulses (µs)\n", + " 'gain': 0.5,\n", + " 'trig_time': 0.05,\n", + " 'ro_len': 0.5,\n", + " 'corr_ch0': 0,\n", + " 'corr_ch1': 1,\n", + " 'corr_len': 100\n", + "}\n", + "\n", + "print(\"Hardware Correlator Configuration:\")\n", + "print(f\"- Correlating ADC channels {config_corr['corr_ch0']} and {config_corr['corr_ch1']}\")\n", + "print(f\"- Correlation length: {config_corr['corr_len']} samples\")\n", + "print(f\"- Pulse delay: {config_corr['delay']} µs\")\n", + "print(\"\\nThe correlator computes: C[τ] = Σ I(t) * I(t+τ) + Q(t) * Q(t+τ)\")\n", + "print(\"This provides real-time cross-correlation between two channels.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. Multi-Tone Generation\n", + "\n", + "You can generate multiple tones simultaneously by summing signals from different DDS channels. This enables:\n", + "- Simultaneous qubit control\n", + "- Frequency comb generation\n", + "- Parallel readout of multiple resonators" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Multi-Tone Generation:\n", + "- Tone 1: 95.0 MHz at gain 0.3\n", + "- Tone 2: 100.0 MHz at gain 0.3\n", + "- Tone 3: 105.0 MHz at gain 0.3\n", + "\n", + "All tones are summed and output on the same DAC channel.\n", + "This is useful for:\n", + " - Simultaneous driving of multiple qubits\n", + " - Frequency-multiplexed readout\n", + " - Creating frequency combs for spectroscopy\n" + ] + } + ], + "source": [ + "class MultiToneProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " # Declare multiple generators on the same DAC channel\n", + " # Each generator can have its own frequency\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1, name='tone1')\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1, name='tone2')\n", + " self.declare_gen(ch=cfg['gen_ch'], nqz=1, name='tone3')\n", + " \n", + " self.declare_readout(ch=cfg['ro_ch'], length=cfg['ro_len'])\n", + "\n", + " # Define constant pulses for each tone\n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"pulse1\",\n", + " style=\"const\", freq=cfg['freq1'],\n", + " length=cfg['pulse_len'], phase=0, gain=cfg['gain1'])\n", + " \n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"pulse2\",\n", + " style=\"const\", freq=cfg['freq2'],\n", + " length=cfg['pulse_len'], phase=0, gain=cfg['gain2'])\n", + " \n", + " self.add_pulse(ch=cfg['gen_ch'], name=\"pulse3\",\n", + " style=\"const\", freq=cfg['freq3'],\n", + " length=cfg['pulse_len'], phase=0, gain=cfg['gain3'])\n", + "\n", + " self.add_readoutconfig(ch=cfg['ro_ch'], name=\"my_ro\",\n", + " freq=cfg['freq1'], gen_ch=cfg['gen_ch'])\n", + "\n", + " def _body(self, cfg):\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'])\n", + " \n", + " # Play all tones simultaneously (summed on the DAC)\n", + " # The QICK automatically sums signals from multiple generators\n", + " self.pulse(ch=cfg['gen_ch'], name=\"pulse1\", t=0)\n", + " self.pulse(ch=cfg['gen_ch'], name=\"pulse2\", t=0)\n", + " self.pulse(ch=cfg['gen_ch'], name=\"pulse3\", t=0)\n", + "\n", + "config_multitone = {\n", + " 'gen_ch': GEN_CH,\n", + " 'ro_ch': RO_CH,\n", + " 'freq1': 95.0, # MHz\n", + " 'freq2': 100.0, # MHz\n", + " 'freq3': 105.0, # MHz\n", + " 'gain1': 0.3,\n", + " 'gain2': 0.3,\n", + " 'gain3': 0.3,\n", + " 'pulse_len': 0.5,\n", + " 'trig_time': 0.05,\n", + " 'ro_len': 0.8\n", + "}\n", + "\n", + "print(\"Multi-Tone Generation:\")\n", + "print(f\"- Tone 1: {config_multitone['freq1']} MHz at gain {config_multitone['gain1']}\")\n", + "print(f\"- Tone 2: {config_multitone['freq2']} MHz at gain {config_multitone['gain2']}\")\n", + "print(f\"- Tone 3: {config_multitone['freq3']} MHz at gain {config_multitone['gain3']}\")\n", + "print(\"\\nAll tones are summed and output on the same DAC channel.\")\n", + "print(\"This is useful for:\")\n", + "print(\" - Simultaneous driving of multiple qubits\")\n", + "print(\" - Frequency-multiplexed readout\")\n", + "print(\" - Creating frequency combs for spectroscopy\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 7. Advanced DSP Examples\n", + "\n", + "Here are some advanced DSP techniques you can implement with the QICK." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Advanced DSP Techniques for QICK:\n", + "\n", + "1. Matched Filters\n", + " Gaussian matched filter taps: [ 4434 5738 7295 9110 11177]...\n", + "\n", + "2. Notch Filters for Interference Rejection\n", + " 10 MHz notch filter taps: [32767 -549 -200 216 543]...\n", + "\n", + "3. Hilbert Transform for Envelope Detection\n", + " Hilbert filter taps: [-2184 0 -2520 0 -2978]...\n" + ] + } + ], + "source": [ + "def advanced_dsp_examples():\n", + " \"\"\"Collection of advanced DSP techniques.\"\"\"\n", + " \n", + " # Example 1: Matched Filter for Optimal SNR\n", + " def matched_filter_coefficients(pulse_shape, num_taps=31):\n", + " \"\"\"\n", + " Create a matched filter for a given pulse shape.\n", + " The matched filter maximizes SNR for known signals.\n", + " \"\"\"\n", + " if isinstance(pulse_shape, str):\n", + " if pulse_shape == 'gaussian':\n", + " # Gaussian pulse shape\n", + " t = np.linspace(-2, 2, num_taps)\n", + " coeffs = np.exp(-t**2 / 2)\n", + " elif pulse_shape == 'square':\n", + " coeffs = np.ones(num_taps)\n", + " else:\n", + " coeffs = np.random.randn(num_taps)\n", + " else:\n", + " coeffs = np.array(pulse_shape)\n", + " \n", + " # Normalize\n", + " coeffs = coeffs / np.sum(np.abs(coeffs))\n", + " coeffs = (coeffs / np.max(np.abs(coeffs)) * 32767).astype(int)\n", + " return coeffs\n", + " \n", + " # Example 2: Notch Filter for Interference Rejection\n", + " def notch_filter_coefficients(notch_freq_mhz, sample_rate_mhz=100, num_taps=31, Q=10):\n", + " \"\"\"\n", + " Design a notch filter to remove a specific interference frequency.\n", + " \"\"\"\n", + " nyquist = sample_rate_mhz / 2\n", + " normalized_notch = notch_freq_mhz / nyquist\n", + " \n", + " # Simple notch using a second-order IIR converted to FIR\n", + " b, a = signal.iirnotch(normalized_notch, Q)\n", + " \n", + " # Convert to FIR (truncate impulse response)\n", + " impulse = np.zeros(num_taps * 2)\n", + " impulse[0] = 1\n", + " response = signal.lfilter(b, a, impulse)\n", + " coeffs = response[:num_taps]\n", + " \n", + " coeffs = (coeffs / np.max(np.abs(coeffs)) * 32767).astype(int)\n", + " return coeffs\n", + " \n", + " # Example 3: Hilbert Transform for Envelope Detection\n", + " def hilbert_coefficients(num_taps=31):\n", + " \"\"\"\n", + " Hilbert transform coefficients for IQ demodulation.\n", + " \"\"\"\n", + " n = np.arange(num_taps) - (num_taps - 1) / 2\n", + " n[n == 0] = 1 # Avoid division by zero\n", + " coeffs = (1 - (-1)**n) / (np.pi * n)\n", + " coeffs = (coeffs / np.max(np.abs(coeffs)) * 32767).astype(int)\n", + " return coeffs\n", + " \n", + " print(\"Advanced DSP Techniques for QICK:\")\n", + " print(\"\\n1. Matched Filters\")\n", + " gaussian_mf = matched_filter_coefficients('gaussian')\n", + " print(f\" Gaussian matched filter taps: {gaussian_mf[:5]}...\")\n", + " \n", + " print(\"\\n2. Notch Filters for Interference Rejection\")\n", + " notch = notch_filter_coefficients(10, Q=30) # 10 MHz interference\n", + " print(f\" 10 MHz notch filter taps: {notch[:5]}...\")\n", + " \n", + " print(\"\\n3. Hilbert Transform for Envelope Detection\")\n", + " hilbert = hilbert_coefficients()\n", + " print(f\" Hilbert filter taps: {hilbert[:5]}...\")\n", + "\n", + "advanced_dsp_examples()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 8. Summary\n", + "\n", + "You have learned:\n", + "- How to design and apply FIR filters for pulse shaping and signal processing\n", + "- How to dynamically tune DDS frequencies during sequences\n", + "- How to use hardware correlators for cross-channel measurements\n", + "- How to generate multi-tone signals for parallel operations\n", + "- Advanced DSP techniques like matched filtering and notch filtering\n", + "\n", + "**Key takeaways:**\n", + "- FIR filters enable real-time spectral shaping on DAC outputs\n", + "- Dynamic DDS tuning allows frequency modulation within sequences\n", + "- Hardware correlators provide real-time cross-correlation at high speed\n", + "- Multi-tone generation enables parallel control and readout\n", + "\n", + "**Next steps:** Proceed to [`13_Custom_Firmware_Integration.ipynb`](./13_Custom_Firmware_Integration.ipynb) to learn about adding custom Verilog modules to the QICK firmware." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/source/tutorials/13_Custom_Firmware_Integration.ipynb b/docs/source/tutorials/13_Custom_Firmware_Integration.ipynb new file mode 100644 index 000000000..6eec0aad3 --- /dev/null +++ b/docs/source/tutorials/13_Custom_Firmware_Integration.ipynb @@ -0,0 +1,765 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 13 - Custom Firmware Integration\n", + "\n", + "**Objective:** Add custom Verilog/VHDL modules, integrate with AXI-lite interface, and rebuild the firmware. This notebook covers:\n", + "- Custom Verilog module development\n", + "- AXI-lite interface integration\n", + "- Firmware rebuild process\n", + "- Python interface to custom registers\n", + "- Debugging and verification\n", + "\n", + "## Prerequisites\n", + "- Vivado installation (2020.1 or later)\n", + "- QICK source code\n", + "- Basic Verilog/VHDL knowledge\n", + "- Familiarity with AXI bus protocol" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Setup" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Board model: RFSoC4x2\n", + "Software version: 0.2.405\n", + "Firmware timestamp: Mon Apr 6 16:32:19 2026\n", + "Available Generators (DACs): 2\n", + "Available Readouts (ADCs): 3\n", + "Reference Clock: 491.52 MHz\n", + "Number of tProc cores: 1\n" + ] + } + ], + "source": [ + "# Standard imports\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import logging\n", + "import os\n", + "import subprocess\n", + "\n", + "from qick import QickSoc\n", + "\n", + "# Setup logging\n", + "logging.basicConfig(level=logging.INFO, format='%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s')\n", + "\n", + "# Connect to the board to check current firmware info\n", + "BITSTREAM_PATH = '/path/to/current_firmware.bit' # <--- CHANGE THIS\n", + "soc = QickSoc(BITSTREAM_PATH)\n", + "\n", + "# Get firmware information\n", + "cfg = soc.get_cfg()\n", + "# Get firmware information\n", + "cfg = soc.get_cfg()\n", + "\n", + "print(f\"Board model: {cfg.get('board', 'Unknown')}\")\n", + "print(f\"Software version: {cfg.get('sw_version', 'Unknown')}\")\n", + "print(f\"Firmware timestamp: {cfg.get('fw_timestamp', 'Unknown')}\")\n", + "\n", + "# In this version, the channels are in 'gens' and 'readouts'.\n", + "print(f\"Available Generators (DACs): {len(cfg.get('gens', []))}\")\n", + "print(f\"Available Readouts (ADCs): {len(cfg.get('readouts', []))}\")\n", + "\n", + "# Useful Additional Information\n", + "if 'refclk_freq' in cfg:\n", + " print(f\"Reference Clock: {cfg['refclk_freq']} MHz\")\n", + "\n", + "# El tProc v2 suele estar en la lista de 'tprocs'\n", + "if 'tprocs' in cfg:\n", + " print(f\"Number of tProc cores: {len(cfg['tprocs'])}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Custom Verilog Module Example\n", + "\n", + "Here's a complete example of a custom Verilog module with AXI-lite interface. This module demonstrates:\n", + "- AXI-lite slave interface for register access\n", + "- Configurable parameters\n", + "- Simple DSP operation (multiply-accumulate)\n", + "- Status registers for debugging" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.1 Custom Module Verilog Code\n", + "\n", + "Create a file named `custom_dsp_module.v`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "verilog_code = '''\n", + "// Custom DSP Module for QICK\n", + "// Supports multiply-accumulate operations with AXI-lite interface\n", + "\n", + "module custom_dsp_module #(\n", + " parameter AXI_ADDR_WIDTH = 32,\n", + " parameter AXI_DATA_WIDTH = 32,\n", + " parameter NUM_REGS = 8\n", + ")(\n", + " input wire clk,\n", + " input wire rst,\n", + " \n", + " // AXI-lite slave interface\n", + " input wire [AXI_ADDR_WIDTH-1:0] s_axi_awaddr,\n", + " input wire s_axi_awvalid,\n", + " output wire s_axi_awready,\n", + " input wire [AXI_DATA_WIDTH-1:0] s_axi_wdata,\n", + " input wire s_axi_wvalid,\n", + " output wire s_axi_wready,\n", + " output wire [1:0] s_axi_bresp,\n", + " output wire s_axi_bvalid,\n", + " input wire s_axi_bready,\n", + " input wire [AXI_ADDR_WIDTH-1:0] s_axi_araddr,\n", + " input wire s_axi_arvalid,\n", + " output wire s_axi_arready,\n", + " output wire [AXI_DATA_WIDTH-1:0] s_axi_rdata,\n", + " output wire [1:0] s_axi_rresp,\n", + " output wire s_axi_rvalid,\n", + " input wire s_axi_rready,\n", + " \n", + " // Custom outputs (can connect to DACs or other modules)\n", + " output reg [31:0] custom_output,\n", + " output reg [31:0] mac_result,\n", + " \n", + " // Status outputs\n", + " output reg [31:0] status,\n", + " output reg interrupt\n", + ");\n", + "\n", + " // Register addresses\n", + " localparam REG_CONTROL = 8'h00;\n", + " localparam REG_STATUS = 8'h04;\n", + " localparam REG_VALUE_A = 8'h08;\n", + " localparam REG_VALUE_B = 8'h0C;\n", + " localparam REG_MAC_RESULT = 8'h10;\n", + " localparam REG_CUSTOM_OUT = 8'h14;\n", + " localparam REG_CONFIG = 8'h18;\n", + " localparam REG_VERSION = 8'hFC;\n", + " \n", + " // Internal registers\n", + " reg [AXI_DATA_WIDTH-1:0] regs [0:NUM_REGS-1];\n", + " \n", + " // Multiply-accumulate state\n", + " reg [63:0] accumulator;\n", + " reg [31:0] value_a, value_b;\n", + " reg mac_busy;\n", + " reg [7:0] mac_counter;\n", + " \n", + " // AXI state machine\n", + " reg [1:0] axi_state;\n", + " reg [AXI_ADDR_WIDTH-1:0] write_addr;\n", + " \n", + " // Initialize registers\n", + " integer i;\n", + " initial begin\n", + " for (i = 0; i < NUM_REGS; i = i + 1) begin\n", + " regs[i] = 32'd0;\n", + " end\n", + " regs[REG_VERSION >> 2] = 32'h00010001; // Version 1.1\n", + " accumulator = 64'd0;\n", + " mac_busy = 1'b0;\n", + " custom_output = 32'd0;\n", + " mac_result = 32'd0;\n", + " status = 32'd0;\n", + " interrupt = 1'b0;\n", + " end\n", + " \n", + " // AXI-lite write channel\n", + " assign s_axi_awready = (axi_state == 2'b01);\n", + " assign s_axi_wready = (axi_state == 2'b01);\n", + " assign s_axi_bresp = 2'b00;\n", + " assign s_axi_bvalid = (axi_state == 2'b10);\n", + " \n", + " // AXI-lite read channel\n", + " assign s_axi_arready = (axi_state == 2'b00);\n", + " assign s_axi_rdata = regs[s_axi_araddr[7:2]];\n", + " assign s_axi_rresp = 2'b00;\n", + " assign s_axi_rvalid = (axi_state == 2'b11);\n", + " \n", + " // AXI-lite state machine\n", + " always @(posedge clk) begin\n", + " if (rst) begin\n", + " axi_state <= 2'b00;\n", + " write_addr <= 32'd0;\n", + " end else begin\n", + " case (axi_state)\n", + " 2'b00: begin // Idle\n", + " if (s_axi_awvalid && s_axi_wvalid) begin\n", + " write_addr <= s_axi_awaddr;\n", + " axi_state <= 2'b01;\n", + " end else if (s_axi_arvalid) begin\n", + " axi_state <= 2'b11;\n", + " end\n", + " end\n", + " 2'b01: begin // Write data received\n", + " regs[write_addr[7:2]] <= s_axi_wdata;\n", + " axi_state <= 2'b10;\n", + " end\n", + " 2'b10: begin // Write response\n", + " if (s_axi_bready) begin\n", + " axi_state <= 2'b00;\n", + " end\n", + " end\n", + " 2'b11: begin // Read response\n", + " if (s_axi_rready) begin\n", + " axi_state <= 2'b00;\n", + " end\n", + " end\n", + " endcase\n", + " end\n", + " end\n", + " \n", + " // Multiply-Accumulate operation\n", + " always @(posedge clk) begin\n", + " if (rst) begin\n", + " accumulator <= 64'd0;\n", + " mac_busy <= 1'b0;\n", + " mac_counter <= 8'd0;\n", + " mac_result <= 32'd0;\n", + " end else begin\n", + " // Check for MAC start command\n", + " if (regs[REG_CONTROL >> 2][0] && !mac_busy) begin\n", + " value_a <= regs[REG_VALUE_A >> 2];\n", + " value_b <= regs[REG_VALUE_B >> 2];\n", + " accumulator <= 64'd0;\n", + " mac_counter <= regs[REG_CONFIG >> 2][7:0];\n", + " mac_busy <= 1'b1;\n", + " regs[REG_CONTROL >> 2][0] <= 1'b0; // Clear start bit\n", + " status[0] <= 1'b1; // MAC busy\n", + " end\n", + " \n", + " // Perform MAC iterations\n", + " if (mac_busy && (mac_counter > 0)) begin\n", + " accumulator <= accumulator + (value_a * value_b);\n", + " mac_counter <= mac_counter - 1;\n", + " end\n", + " \n", + " // MAC complete\n", + " if (mac_busy && (mac_counter == 0)) begin\n", + " mac_busy <= 1'b0;\n", + " mac_result <= accumulator[31:0];\n", + " regs[REG_MAC_RESULT >> 2] <= accumulator[31:0];\n", + " status[0] <= 1'b0; // MAC done\n", + " status[1] <= 1'b1; // MAC complete flag\n", + " interrupt <= 1'b1;\n", + " end\n", + " \n", + " // Clear interrupt on read\n", + " if (s_axi_arvalid && (s_axi_araddr[7:2] == (REG_STATUS >> 2))) begin\n", + " interrupt <= 1'b0;\n", + " status[1] <= 1'b0;\n", + " end\n", + " end\n", + " end\n", + " \n", + " // Custom output from register\n", + " always @(posedge clk) begin\n", + " if (rst) begin\n", + " custom_output <= 32'd0;\n", + " end else begin\n", + " custom_output <= regs[REG_CUSTOM_OUT >> 2];\n", + " end\n", + " end\n", + " \n", + "endmodule\n", + "'''\n", + "\n", + "print(\"=== Custom Verilog Module ===\")\n", + "print(verilog_code[:500] + \"...\")\n", + "print(f\"\\nTotal module size: {len(verilog_code)} characters\")\n", + "print(\"\\nKey features:\")\n", + "print(\" - AXI-lite slave interface for register access\")\n", + "print(\" - Multiply-accumulate (MAC) operation\")\n", + "print(\" - Status and interrupt generation\")\n", + "print(\" - Configurable parameters\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.2 Integration Steps\n", + "\n", + "Follow these steps to integrate the custom module into the QICK firmware." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def print_integration_steps():\n", + " \"\"\"Print the firmware integration procedure.\"\"\"\n", + " \n", + " steps = \"\"\"\n", + " ========================================\n", + " STEP 1: Add Module to QICK Source\n", + " ========================================\n", + " \n", + " # Copy the Verilog file to the QICK IP directory\n", + " cp custom_dsp_module.v $QICK_PATH/firmware/ip/\n", + " \n", + " # Add the module to the IP catalog (create a simple wrapper if needed)\n", + " cd $QICK_PATH/firmware\n", + " \n", + " ========================================\n", + " STEP 2: Update Block Design (TCL Script)\n", + " ========================================\n", + " \n", + " # Create a TCL script to add the module to the block design\n", + " cat > add_custom_module.tcl << 'EOF'\n", + " # Create and configure custom module cell\n", + " create_bd_cell -type ip -vlnv user:user:custom_dsp_module:1.0 custom_dsp_module_0\n", + " \n", + " # Connect AXI-lite interface to interconnect\n", + " connect_bd_intf_net -intf_net axi_interconnect_0_m00_axi \\\\\n", + " [get_bd_intf_pins custom_dsp_module_0/s_axi]\n", + " \n", + " # Connect clocks and resets\n", + " connect_bd_net -net clk_wiz_0_clk_out1 \\\\\n", + " [get_bd_pins custom_dsp_module_0/clk]\n", + " connect_bd_net -net rst_clk_wiz_0_100M_peripheral_aresetn \\\\\n", + " [get_bd_pins custom_dsp_module_0/rst]\n", + " \n", + " # Assign address range (check available address space)\n", + " assign_bd_address -target_address_space /processing_system7_0/Data \\\\\n", + " [get_bd_addr_segs custom_dsp_module_0/s_axi/reg0] \\\\\n", + " -range 0x1000 -offset 0x43C00000\n", + " EOF\n", + " \n", + " # Run TCL script in Vivado\n", + " vivado -source add_custom_module.tcl $QICK_PATH/firmware/projects/qick_tprocv2_4x2_standard_b_5/qick_tprocv2_4x2_standard_b_5.xpr\n", + " \n", + " ========================================\n", + " STEP 3: Rebuild Firmware\n", + " ========================================\n", + " \n", + " cd $QICK_PATH/firmware\n", + " make clean\n", + " make all\n", + " \n", + " # The new bitstream will be in:\n", + " # projects/qick_tprocv2_4x2_standard_b_5/out/qick_4x2.bit\n", + " \"\"\"\n", + " \n", + " print(steps)\n", + "\n", + "print_integration_steps()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Python Interface to Custom Module\n", + "\n", + "Once the firmware is rebuilt with your custom module, you can interface with it from Python using AXI-lite reads and writes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class CustomDSPModule:\n", + " \"\"\"Python interface for the custom DSP module.\"\"\"\n", + " \n", + " # Register offsets (must match Verilog defines)\n", + " REG_CONTROL = 0x00\n", + " REG_STATUS = 0x04\n", + " REG_VALUE_A = 0x08\n", + " REG_VALUE_B = 0x0C\n", + " REG_MAC_RESULT = 0x10\n", + " REG_CUSTOM_OUT = 0x14\n", + " REG_CONFIG = 0x18\n", + " REG_VERSION = 0xFC\n", + " \n", + " def __init__(self, soc, base_addr=0x43C00000):\n", + " \"\"\"\n", + " Initialize the custom module interface.\n", + " \n", + " Parameters:\n", + " - soc: QickSoc instance\n", + " - base_addr: AXI base address of the custom module\n", + " \"\"\"\n", + " self.soc = soc\n", + " self.base = base_addr\n", + " self._check_version()\n", + " \n", + " def _check_version(self):\n", + " \"\"\"Verify the module is present and get version.\"\"\"\n", + " try:\n", + " version = self.read_reg(self.REG_VERSION)\n", + " major = (version >> 16) & 0xFFFF\n", + " minor = version & 0xFFFF\n", + " print(f\"Custom module detected: version {major}.{minor}\")\n", + " except Exception as e:\n", + " print(f\"Warning: Could not read custom module version: {e}\")\n", + " \n", + " def write_reg(self, offset, value):\n", + " \"\"\"Write to a register.\"\"\"\n", + " self.soc.axilite_write(self.base + offset, value)\n", + " \n", + " def read_reg(self, offset):\n", + " \"\"\"Read from a register.\"\"\"\n", + " return self.soc.axilite_read(self.base + offset)\n", + " \n", + " def set_value_a(self, value):\n", + " \"\"\"Set value A for MAC operation.\"\"\"\n", + " self.write_reg(self.REG_VALUE_A, value & 0xFFFFFFFF)\n", + " \n", + " def set_value_b(self, value):\n", + " \"\"\"Set value B for MAC operation.\"\"\"\n", + " self.write_reg(self.REG_VALUE_B, value & 0xFFFFFFFF)\n", + " \n", + " def set_custom_output(self, value):\n", + " \"\"\"Set the custom output value.\"\"\"\n", + " self.write_reg(self.REG_CUSTOM_OUT, value & 0xFFFFFFFF)\n", + " \n", + " def set_config(self, num_iterations):\n", + " \"\"\"Configure MAC operation parameters.\"\"\"\n", + " self.write_reg(self.REG_CONFIG, num_iterations & 0xFF)\n", + " \n", + " def start_mac(self):\n", + " \"\"\"Start the multiply-accumulate operation.\"\"\"\n", + " self.write_reg(self.REG_CONTROL, 0x01)\n", + " \n", + " def is_mac_busy(self):\n", + " \"\"\"Check if MAC operation is in progress.\"\"\"\n", + " status = self.read_reg(self.REG_STATUS)\n", + " return (status & 0x01) != 0\n", + " \n", + " def get_mac_result(self):\n", + " \"\"\"Get the MAC result (blocking until complete).\"\"\"\n", + " # Wait for completion (or check interrupt)\n", + " import time\n", + " timeout = 0.001 # 1 ms timeout\n", + " start_time = time.time()\n", + " \n", + " while self.is_mac_busy():\n", + " if time.time() - start_time > timeout:\n", + " raise TimeoutError(\"MAC operation timed out\")\n", + " \n", + " return self.read_reg(self.REG_MAC_RESULT)\n", + " \n", + " def multiply_accumulate(self, a, b, num_iterations=1):\n", + " \"\"\"\n", + " Perform a multiply-accumulate operation on hardware.\n", + " \n", + " Returns a * b * num_iterations (in hardware, with 32-bit precision)\n", + " \"\"\"\n", + " self.set_value_a(a)\n", + " self.set_value_b(b)\n", + " self.set_config(num_iterations)\n", + " self.start_mac()\n", + " return self.get_mac_result()\n", + " \n", + " def get_status_string(self):\n", + " \"\"\"Get human-readable status.\"\"\"\n", + " status = self.read_reg(self.REG_STATUS)\n", + " bits = []\n", + " if status & 0x01:\n", + " bits.append(\"MAC_BUSY\")\n", + " if status & 0x02:\n", + " bits.append(\"MAC_DONE\")\n", + " return f\"Status: {', '.join(bits) if bits else 'IDLE'} (0x{status:08X})\"\n", + "\n", + "\n", + "# Example usage (after firmware is rebuilt)\n", + "def example_custom_module_usage():\n", + " \"\"\"Example of using the custom module.\"\"\"\n", + " \n", + " print(\"=== Custom Module Usage Example ===\\n\")\n", + " \n", + " # Initialize the custom module (use correct base address)\n", + " # custom = CustomDSPModule(soc, base_addr=0x43C00000)\n", + " \n", + " # Test basic operations\n", + " # custom.set_custom_output(0xDEADBEEF)\n", + " # print(f\"Custom output set to: 0x{custom.read_reg(CustomDSPModule.REG_CUSTOM_OUT):08X}\")\n", + " \n", + " # Perform MAC operation\n", + " # result = custom.multiply_accumulate(1000, 2000, num_iterations=5)\n", + " # print(f\"MAC result: {result}\")\n", + " # Expected: 1000 * 2000 * 5 = 10,000,000\n", + " \n", + " print(\"Example operations:\")\n", + " print(\" - Set custom output: custom.set_custom_output(0xDEADBEEF)\")\n", + " print(\" - Read status: custom.get_status_string()\")\n", + " print(\" - MAC operation: result = custom.multiply_accumulate(1000, 2000, 5)\")\n", + "\n", + "example_custom_module_usage()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Debugging Custom Firmware\n", + "\n", + "Here are techniques for debugging custom firmware modules." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def debug_firmware_techniques():\n", + " \"\"\"Debugging techniques for custom firmware.\"\"\"\n", + " \n", + " print(\"=== Firmware Debugging Techniques ===\\n\")\n", + " \n", + " print(\"1. Integrated Logic Analyzer (ILA)\")\n", + " print(\" - Add ILA cores to capture internal signals\")\n", + " print(\" - Use Vivado hardware manager to view waveforms\")\n", + " print(\" - Example TCL:\")\n", + " print(\" create_bd_cell -type ip -vlnv xilinx.com:ip:ila:6.2 ila_0\")\n", + " print(\" connect_bd_net [get_bd_pins custom_module/signal] [get_bd_pins ila_0/probe0]\\n\")\n", + " \n", + " print(\"2. Virtual I/O (VIO) for Real-Time Control\")\n", + " print(\" - Use VIO to read/write signals during runtime\")\n", + " print(\" - Example TCL:\")\n", + " print(\" create_bd_cell -type ip -vlnv xilinx.com:ip:vio:3.0 vio_0\\n\")\n", + " \n", + " print(\"3. AXI Verification\")\n", + " print(\" - Use AXI VIP for protocol checking\")\n", + " print(\" - Simulate with XSIM or ModelSim\")\n", + " print(\" - Check address mapping in the address editor\\n\")\n", + " \n", + " print(\"4. Python-Based Debugging\")\n", + " print(\" - Read/write registers to verify functionality\")\n", + " print(\" - Use timeout-based polling for status bits\")\n", + " print(\" - Implement diagnostic functions\")\n", + " print(\"\")\n", + " \n", + " print(\"5. Common Issues and Solutions\")\n", + " issues = [\n", + " (\"Clock domain crossing\", \"Use proper synchronizers or CDC modules\"),\n", + " (\"AXI address conflict\", \"Check address ranges in address editor\"),\n", + " (\"Timing closure failures\", \"Add pipeline registers or reduce logic depth\"),\n", + " (\"Missing reset connections\", \"Verify all modules receive reset signals\"),\n", + " (\"Incorrect AXI handshake\", \"Follow AXI-lite protocol specification\")\n", + " ]\n", + " \n", + " for issue, solution in issues:\n", + " print(f\" - {issue}: {solution}\")\n", + "\n", + "debug_firmware_techniques()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Firmware Verification Test\n", + "\n", + "After rebuilding the firmware, run this verification test to ensure everything works." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def verify_custom_firmware(soc, custom_module, expected_version=\"1.0\"):\n", + " \"\"\"\n", + " Comprehensive verification test for custom firmware.\n", + " \n", + " Parameters:\n", + " - soc: QickSoc instance\n", + " - custom_module: CustomDSPModule instance\n", + " - expected_version: Expected version string\n", + " \n", + " Returns:\n", + " - True if all tests pass, False otherwise\n", + " \"\"\"\n", + " print(\"=== Firmware Verification ===\\n\")\n", + " \n", + " tests_passed = 0\n", + " tests_total = 0\n", + " \n", + " # Test 1: Version check\n", + " tests_total += 1\n", + " try:\n", + " version = custom_module.read_reg(CustomDSPModule.REG_VERSION)\n", + " version_str = f\"{(version >> 16) & 0xFFFF}.{version & 0xFFFF}\"\n", + " print(f\"✓ Version: {version_str}\")\n", + " tests_passed += 1\n", + " except Exception as e:\n", + " print(f\"✗ Version check failed: {e}\")\n", + " \n", + " # Test 2: Register read/write\n", + " tests_total += 1\n", + " test_value = 0x12345678\n", + " try:\n", + " custom_module.write_reg(CustomDSPModule.REG_CUSTOM_OUT, test_value)\n", + " read_value = custom_module.read_reg(CustomDSPModule.REG_CUSTOM_OUT)\n", + " if read_value == test_value:\n", + " print(f\"✓ Register write/read: OK (0x{read_value:08X})\")\n", + " tests_passed += 1\n", + " else:\n", + " print(f\"✗ Register mismatch: wrote 0x{test_value:08X}, read 0x{read_value:08X}\")\n", + " except Exception as e:\n", + " print(f\"✗ Register test failed: {e}\")\n", + " \n", + " # Test 3: MAC operation\n", + " tests_total += 1\n", + " try:\n", + " a, b, n = 100, 200, 3\n", + " expected = a * b * n\n", + " result = custom_module.multiply_accumulate(a, b, n)\n", + " if result == expected:\n", + " print(f\"✓ MAC test: {a} * {b} * {n} = {result}\")\n", + " tests_passed += 1\n", + " else:\n", + " print(f\"✗ MAC test: expected {expected}, got {result}\")\n", + " except Exception as e:\n", + " print(f\"✗ MAC test failed: {e}\")\n", + " \n", + " # Test 4: Basic QICK functionality\n", + " tests_total += 1\n", + " try:\n", + " cfg = soc.get_cfg()\n", + " print(f\"✓ QICK readout: {cfg['adcs']} ADCs, {cfg['dacs']} DACs\")\n", + " tests_passed += 1\n", + " except Exception as e:\n", + " print(f\"✗ QICK test failed: {e}\")\n", + " \n", + " print(f\"\\nTest Results: {tests_passed}/{tests_total} passed\")\n", + " return tests_passed == tests_total\n", + "\n", + "print(\"Verification function ready.\")\n", + "print(\"After rebuilding firmware, run:\")\n", + "print(\" custom = CustomDSPModule(soc, base_addr=0x43C00000)\")\n", + "print(\" verify_custom_firmware(soc, custom)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. Resources and References" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def print_resources():\n", + " \"\"\"Print useful resources for custom firmware development.\"\"\"\n", + " \n", + " resources = {\n", + " \"QICK Documentation\": \"https://qick.readthedocs.io/en/latest/firmware.html\",\n", + " \"Vivado AXI Reference\": \"https://www.xilinx.com/support/documentation/ip_documentation/axi_ref_guide/latest/ug1037-vivado-axi-reference-guide.pdf\",\n", + " \"QICK GitHub\": \"https://github.com/openquantumhardware/qick\",\n", + " \"Xilinx Vivado Documentation\": \"https://www.xilinx.com/support/documentation-navigation/design-hubs/dh004-ultrascale-plus-vivado-design-hub.html\",\n", + " \"AXI-lite Protocol\": \"https://developer.arm.com/documentation/ihi0022/latest/\"\n", + " }\n", + " \n", + " print(\"=== Useful Resources ===\\n\")\n", + " for name, url in resources.items():\n", + " print(f\"- {name}: {url}\")\n", + " \n", + " print(\"\\n=== Key Commands Reference ===\\n\")\n", + " cmds = [\n", + " (\"make all\", \"Build firmware\"),\n", + " (\"make clean\", \"Clean build artifacts\"),\n", + " (\"vivado -source script.tcl project.xpr\", \"Run TCL script in Vivado\"),\n", + " (\"report_ip_status\", \"Check IP status in Vivado\"),\n", + " (\"validate_bd_design\", \"Validate block design\"),\n", + " (\"write_bitstream\", \"Generate bitstream\"),\n", + " ]\n", + " \n", + " for cmd, desc in cmds:\n", + " print(f\" {cmd}: {desc}\")\n", + "\n", + "print_resources()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 7. Summary\n", + "\n", + "You have learned:\n", + "- How to create custom Verilog modules with AXI-lite interfaces\n", + "- Integration steps for adding custom modules to QICK firmware\n", + "- How to rebuild the firmware with custom modules\n", + "- Python interface development for custom registers\n", + "- Debugging techniques for custom firmware\n", + "- Verification procedures for new firmware\n", + "\n", + "**Key takeaways:**\n", + "- Custom modules extend QICK functionality for specialized applications\n", + "- AXI-lite provides a standard interface for register access\n", + "- Use Vivado's IP integrator for block design modifications\n", + "- Always verify custom firmware with test routines\n", + "- Use ILA/VIO cores for hardware debugging\n", + "\n", + "**Next steps:**\n", + "\n", + "- For multi-board synchronization without XCOM hardware, see [`10_Multi_Board_Synchronization.ipynb`](./10_Multi_Board_Synchronization.ipynb)\n", + "- For advanced multi-board networking with XCOM, see [`14_XCOM_Network_Synchronization.ipynb`](./14_XCOM_Network_Synchronization.ipynb)\n", + "- Review the QICK firmware documentation for detailed build instructions\n", + "- Experiment with simple custom modules before complex designs\n", + "- Join the QICK community for support and collaboration" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/source/tutorials/14_XCOM_Network_Synchronization.ipynb b/docs/source/tutorials/14_XCOM_Network_Synchronization.ipynb new file mode 100644 index 000000000..87aa82c6a --- /dev/null +++ b/docs/source/tutorials/14_XCOM_Network_Synchronization.ipynb @@ -0,0 +1,1067 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 14 - XCOM Network Synchronization\n", + "\n", + "**Objective:** Learn how to synchronize multiple QICK boards and exchange low-latency data using the XCOM network. This notebook covers:\n", + "\n", + "- XCOM architecture overview (full mesh network, deterministic latency)\n", + "- Hardware setup (FMC transceiver board, external hub)\n", + "- Initializing the XCOM network (AUTO_ID, master/slave configuration)\n", + "- Sending and receiving data between boards (8-bit, 16-bit, 32-bit)\n", + "- Loopback testing and latency measurement\n", + "- tProc integration for real-time communication\n", + "- Debugging XCOM (status registers, debug registers)\n", + "- Synchronizing tProc absolute clocks across multiple boards\n", + "\n", + "**Prerequisites:**\n", + "- Two or more QICK boards with XCOM FMC transceiver boards\n", + "- External XCOM hub connecting all boards\n", + "- Stable external reference clock (e.g., rubidium clock)\n", + "- Completed basic tutorials (00-05)\n", + "\n", + "**References:**\n", + "- XCOM Paper: arXiv:2603.18977v1\n", + "- QICK XCOM driver: `qick.ip.QICK_Xcom`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. XCOM Overview\n", + "\n", + "XCOM (X - Communication) is a **full mesh network** that enables:\n", + "\n", + "- **Synchronization** of multiple QICK boards with <100 ps skew\n", + "- **Low-latency communication** (186 ns per 32-bit word, can be reduced to 62 ns)\n", + "- **Deterministic message exchange** without central control\n", + "- **All-to-all simultaneous communication** on different channels\n", + "- **tProc integration** for real-time data exchange\n", + "\n", + "### Hardware Requirements\n", + "\n", + "```\n", + "┌─────────────────────────────────────────────────────────────────────────────┐\n", + "│ XCOM Network Topology │\n", + "├─────────────────────────────────────────────────────────────────────────────┤\n", + "│ │\n", + "│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │\n", + "│ │ QICK #1 │ │ QICK #2 │ │ QICK #3 │ │ QICK #4 │ │\n", + "│ │ (Master) │ │ (Slave) │ │ (Slave) │ │ (Slave) │ │\n", + "│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │\n", + "│ │ │ │ │ │\n", + "│ ▼ ▼ ▼ ▼ │\n", + "│ ┌─────────────────────────────────────────────────────────────────┐ │\n", + "│ │ XCOM Hub (Fanout Buffers) │ │\n", + "│ └─────────────────────────────────────────────────────────────────┘ │\n", + "│ │\n", + "│ • Each board has a dedicated Tx channel (LVDS @ up to 312.9 MHz) │\n", + "│ • All boards listen on all Rx channels (full mesh) │\n", + "│ • External reference clock (e.g., 100 MHz rubidium) for frequency sync │\n", + "│ │\n", + "└─────────────────────────────────────────────────────────────────────────────┘\n", + "```\n", + "\n", + "**Supported boards:** Up to 15 boards (prototype supports 5)\n", + "\n", + "**Key capabilities:**\n", + "- Sub-picosecond timing jitter with nested zero-delay PLL mode\n", + "- Multi-tile sync (MTS) for DAC/ADC alignment across boards\n", + "- 48-bit absolute clock counter synchronized across all boards\n", + "- Deterministic communication latency (independent of network traffic)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Setup and Initialization" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Standard imports\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import time\n", + "import logging\n", + "\n", + "from qick import *\n", + "from qick.asm_v2 import AveragerProgramV2\n", + "from qick.tprocv2_assembler import Assembler\n", + "\n", + "# Setup logging\n", + "logging.basicConfig(level=logging.INFO, format='%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s')\n", + "\n", + "# Connect to the board (adjust path to your firmware with XCOM support)\n", + "# For multi-board setup, create separate Soc instances for each board\n", + "BITSTREAM_PATH = '/path/to/your/xcom_firmware.bit' # <--- CHANGE THIS\n", + "soc = QickSoc(BITSTREAM_PATH, external_clk=True, force_init_clks=True)\n", + "soccfg = soc\n", + "\n", + "print(f\"Connected to QICK board\")\n", + "print(f\"Firmware version: {soccfg.get('fw_version', 'Unknown')}\")\n", + "print(f\"XCOM available: {hasattr(soc, 'xcom_0')}\")\n", + "\n", + "# For multi-board experiments, you would connect to each board separately:\n", + "# soc_master = QickSoc('master_firmware.bit', external_clk=True)\n", + "# soc_slave1 = QickSoc('slave1_firmware.bit', external_clk=True)\n", + "# soc_slave2 = QickSoc('slave2_firmware.bit', external_clk=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.1 Initialize Clock and Tile Synchronization\n", + "\n", + "Before using XCOM, the board clocks and DAC/ADC tiles must be synchronized." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Initialize tile synchronization (required for multi-board alignment)\n", + "print(\"Initializing tile synchronization...\")\n", + "soc.init_tile_sync()\n", + "soc.verify_clock_tree()\n", + "soc.sync_tiles()\n", + "print(\"Tile synchronization complete.\")\n", + "\n", + "# Verify external clock is locked\n", + "print(f\"External clock locked: {soc.check_ext_clk()}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. XCOM Driver Overview\n", + "\n", + "The `QICK_Xcom` class provides the Python interface to the XCOM hardware. It inherits from `SocIP` and uses AXI-lite for register access." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Display XCOM registers and opcodes\n", + "print(\"=== XCOM Registers ===\")\n", + "for reg_name, reg_addr in soc.xcom_0.REGISTERS.items():\n", + " print(f\" {reg_name:15} : address {reg_addr}\")\n", + "\n", + "print(\"\\n=== XCOM Opcodes ===\")\n", + "for op_name, op_code in soc.xcom_0.opcodes.items():\n", + " print(f\" {op_name:20} : {op_code}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.1 Key XCOM Operations\n", + "\n", + "| Method | Opcode | Description |\n", + "|--------|--------|-------------|\n", + "| `auto_id()` | XCOM_AUTO_ID | Auto-assign network IDs to all boards |\n", + "| `set_local_id(chid)` | XCOM_SET_ID | Manually set this board's ID |\n", + "| `send_byte(data, dst, reg)` | XCOM_SEND_8BIT_1/2 | Send 8 bits to board `dst` |\n", + "| `send_half_word(data, dst, reg)` | XCOM_SEND_16BIT_1/2 | Send 16 bits to board `dst` |\n", + "| `send_word(data, dst, reg)` | XCOM_SEND_32BIT_1/2 | Send 32 bits to board `dst` |\n", + "| `set_flag(dst)` | XCOM_SET_FLAG | Set flag on destination board |\n", + "| `clear_flag(dst)` | XCOM_CLEAR_FLAG | Clear flag on destination board |\n", + "| `run_cmd(cmd, dt1, dt2)` | (any) | Execute any opcode with data |\n", + "\n", + "**Note:** `reg` parameter (1 or 2) selects which destination register to write to." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Network Configuration\n", + "\n", + "### 4.1 Reset and Auto-ID\n", + "\n", + "The first step is to reset the XCOM network and assign IDs to all connected boards." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Reset the XCOM network\n", + "print(\"Resetting XCOM network...\")\n", + "soc.xcom_0.run_cmd(soc.xcom_0.opcodes['XCOM_RST'], 0, 0)\n", + "time.sleep(0.1)\n", + "\n", + "# Run AUTO_ID to discover and assign IDs to all boards\n", + "print(\"Running AUTO_ID...\")\n", + "soc.xcom_0.run_cmd(soc.xcom_0.opcodes['XCOM_AUTO_ID'], 0, 0)\n", + "time.sleep(0.5)\n", + "\n", + "# Set local board ID (master board in this example)\n", + "BOARD_ID_MASTER = 2\n", + "soc.xcom_0.set_local_id(BOARD_ID_MASTER)\n", + "print(f\"Local board ID set to: {BOARD_ID_MASTER}\")\n", + "\n", + "# Re-run AUTO_ID to confirm\n", + "soc.xcom_0.auto_id()\n", + "time.sleep(0.1)\n", + "\n", + "# Configure XCOM (enable certain features)\n", + "# 0x400 typically enables the XCOM interface\n", + "soc.xcom_0.xcom_cfg = 0 + 0x400\n", + "print(f\"XCOM config: 0x{soc.xcom_0.xcom_cfg:04X}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 4.2 Verify Configuration\n", + "\n", + "Check the status and register values to ensure proper configuration." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Print XCOM status\n", + "soc.xcom_0.print_status()\n", + "\n", + "# Print all AXI registers\n", + "print(\"\\n\")\n", + "soc.xcom_0.print_axi_regs()\n", + "\n", + "# Print debug information\n", + "print(\"\\n\")\n", + "soc.xcom_0.print_debug()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Sending Data Between Boards\n", + "\n", + "### 5.1 Sending 8-bit Data\n", + "\n", + "Use `send_byte()` to transmit 8-bit values to another board." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Send 8-bit data to another board (e.g., board ID 5)\n", + "DEST_BOARD = 5\n", + "test_byte = 0xAA\n", + "\n", + "print(f\"Sending 8-bit data (0x{test_byte:02X}) to board {DEST_BOARD}...\")\n", + "soc.xcom_0.send_byte(test_byte, DEST_BOARD, reg=2)\n", + "print(\"Data sent.\")\n", + "\n", + "# For multi-board setup, you would read the data on the destination board:\n", + "# received_data = soc_slave.xcom_0.mem # Read from XCOM memory" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 5.2 Sending 16-bit Data\n", + "\n", + "Use `send_half_word()` to transmit 16-bit values." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Send 16-bit data\n", + "test_half_word = 0xABCD\n", + "\n", + "print(f\"Sending 16-bit data (0x{test_half_word:04X}) to board {DEST_BOARD}...\")\n", + "soc.xcom_0.send_half_word(test_half_word, DEST_BOARD, reg=2)\n", + "print(\"Data sent.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 5.3 Sending 32-bit Data\n", + "\n", + "Use `send_word()` to transmit 32-bit values." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Send 32-bit data\n", + "test_word = 0xDEADBEEF\n", + "\n", + "print(f\"Sending 32-bit data (0x{test_word:08X}) to board {DEST_BOARD}...\")\n", + "soc.xcom_0.send_word(test_word, DEST_BOARD, reg=2)\n", + "print(\"Data sent.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 5.4 Writing to XCOM Memory\n", + "\n", + "XCOM has internal memory (16x32-bit) that can be written to and read from." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Write to XCOM memory on destination board\n", + "dest_addr = 5\n", + "data_to_write = 350\n", + "\n", + "print(f\"Writing {data_to_write} to memory address {dest_addr} on board {DEST_BOARD}\")\n", + "soc.xcom_0.run_cmd(soc.xcom_0.opcodes['XCOM_WRITE_MEM'], dest_addr, data_to_write)\n", + "\n", + "# Read back the memory\n", + "print(\"\\nReading XCOM memory (local board):\")\n", + "print(\"addr\\tvalue\")\n", + "for i in range(16):\n", + " soc.xcom_0.axi_addr = i\n", + " print(f\"{i:3d}\\t{soc.xcom_0.mem}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. tProc Integration for XCOM\n", + "\n", + "XCOM can be controlled directly from the tProc using assembly instructions. The `PA` (Peripheral Access) instruction is the primary mechanism for tProc-XCOM interaction." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Example assembly program for XCOM communication from tProc\n", + "xcom_tproc_asm = \"\"\"\n", + "// XCOM Communication Test Program (tProc side)\n", + "// Sends data to another board via XCOM\n", + "\n", + "// Initialize registers\n", + "REG_WR r1 imm #1 // Configuration register 1\n", + "REG_WR r2 imm #2 // Configuration register 2\n", + "REG_WR r3 imm #3 // Configuration register 3\n", + "REG_WR r4 imm #4 // Configuration register 4\n", + "REG_WR r5 imm #5 // Destination board ID\n", + "REG_WR r6 imm #424 // Data to send\n", + "\n", + "// Write to XCOM control/configuration\n", + "// ctrl_csf_qpa = clear flag in cfg/cntl\n", + "// cfg_src_qpa = configure source\n", + "\n", + "// Trigger output pin for scope synchronization\n", + "TRIG p0 set\n", + "\n", + "// Write to XCOM memory (WRITE_MEM operation)\n", + "REG_WR s_ctrl imm ctrl_csf_qpa // Clear flag in cfg/cntl\n", + "WAIT qpa_rdy // Wait for peripheral ready\n", + "PA 7 r2 r6 // Peripheral access: write r6 using config in r2\n", + "WAIT qpa_dt // Wait for data transfer complete\n", + "\n", + "// Clear trigger\n", + "TRIG p0 clr\n", + "\n", + "// Set flag on destination board\n", + "WAIT qpa_rdy\n", + "PA 1 r5 // Set flag on board in r5\n", + "WAIT qpa_dt\n", + "\n", + ".END\n", + "\"\"\"\n", + "\n", + "# Compile the assembly\n", + "p_txt, p_bin = Assembler.str_asm2bin(xcom_tproc_asm)\n", + "print(f\"Assembly compiled: {len(p_bin)} instructions\")\n", + "print(\"\\nAssembly code:\")\n", + "print(p_txt)\n", + "\n", + "# Load the program into tProc program memory\n", + "# Note: The method name may vary based on your firmware version\n", + "# soc.qick_processor_0.load_mem(mem_sel='pmem', buff_in=p_bin, check=False)\n", + "print(\"\\nProgram ready to load to tProc.\")\n", + "print(\"Uncomment the load_mem line and adjust the method name as needed for your firmware.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 6.1 tProc Peripheral Access (PA) Instruction\n", + "\n", + "The `PA` instruction is used for peripheral access. The syntax is:\n", + "\n", + "```\n", + "PA \n", + "```\n", + "\n", + "Where:\n", + "- `cfg_reg`: Configuration register (controls the operation)\n", + "- `addr_reg`: Address/target register (e.g., destination board ID)\n", + "- `data_reg`: Data register (value to send)\n", + "\n", + "**Common PA operations:**\n", + "\n", + "| PA cfg | Operation | Description |\n", + "|--------|-----------|-------------|\n", + "| 0 | CLEAR_FLAG | Clear flag on destination board |\n", + "| 1 | SET_FLAG | Set flag on destination board |\n", + "| 6 | XCOM QCTRL | XCOM control operation |\n", + "| 7 | WRITE_MEM | Write to XCOM memory |" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 7. Master-Slave Communication Example\n", + "\n", + "In a multi-board setup, one board acts as the **master** and others as **slaves**. The master can:\n", + "- Broadcast reset/start commands to synchronize absolute clocks\n", + "- Send data to specific slaves\n", + "- Receive data from slaves\n", + "- Coordinate multi-board experiments\n", + "\n", + "### 7.1 Master Board Configuration" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Master board setup (run on the board designated as master)\n", + "def setup_master_board(soc, master_id=2):\n", + " \"\"\"Configure a board as XCOM master.\"\"\"\n", + " print(\"Setting up master board...\")\n", + " \n", + " # Reset XCOM\n", + " soc.xcom_0.run_cmd(soc.xcom_0.opcodes['XCOM_RST'], 0, 0)\n", + " time.sleep(0.1)\n", + " \n", + " # Auto-assign IDs\n", + " soc.xcom_0.run_cmd(soc.xcom_0.opcodes['XCOM_AUTO_ID'], 0, 0)\n", + " time.sleep(0.5)\n", + " \n", + " # Set local ID\n", + " soc.xcom_0.set_local_id(master_id)\n", + " \n", + " # Configure XCOM\n", + " soc.xcom_0.xcom_cfg = 0 + 0x400 + 0x100 # Additional config for master\n", + " \n", + " print(f\"Master board configured with ID: {master_id}\")\n", + " return True\n", + "\n", + "# Slave board configuration (run on each slave board)\n", + "def setup_slave_board(soc, slave_id):\n", + " \"\"\"Configure a board as XCOM slave.\"\"\"\n", + " print(f\"Setting up slave board with ID: {slave_id}...\")\n", + " \n", + " # Reset XCOM\n", + " soc.xcom_0.run_cmd(soc.xcom_0.opcodes['XCOM_RST'], 0, 0)\n", + " time.sleep(0.1)\n", + " \n", + " # Auto-assign IDs\n", + " soc.xcom_0.run_cmd(soc.xcom_0.opcodes['XCOM_AUTO_ID'], 0, 0)\n", + " time.sleep(0.5)\n", + " \n", + " # Set local ID\n", + " soc.xcom_0.set_local_id(slave_id)\n", + " \n", + " # Configure XCOM\n", + " soc.xcom_0.xcom_cfg = 0 + 0x400\n", + " \n", + " print(f\"Slave board configured with ID: {slave_id}\")\n", + " return True\n", + "\n", + "print(\"Master/slave configuration functions defined.\")\n", + "print(\"\\nFor multi-board experiments:\")\n", + "print(\" master = setup_master_board(soc_master, master_id=2)\")\n", + "print(\" slave1 = setup_slave_board(soc_slave1, slave_id=5)\")\n", + "print(\" slave2 = setup_slave_board(soc_slave2, slave_id=7)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 7.2 Sending Data from Master to Slave\n", + "\n", + "Once configured, the master can send data to any slave." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Example: Master sending a ramp pattern to a slave\n", + "def master_send_ramp(soc_master, dest_slave_id, num_values=100):\n", + " \"\"\"Send a ramp of values from master to slave.\"\"\"\n", + " print(f\"Master sending {num_values} values to slave {dest_slave_id}...\")\n", + " \n", + " start_time = time.time()\n", + " \n", + " for i in range(num_values):\n", + " # Send 16-bit value\n", + " soc_master.xcom_0.send_half_word(i, dest_slave_id, reg=2)\n", + " # Optional: wait for acknowledgment\n", + " # while soc_master.xcom_0.mem == 0:\n", + " # pass\n", + " \n", + " elapsed = time.time() - start_time\n", + " print(f\"Sent {num_values} values in {elapsed:.3f}s ({num_values/elapsed:.0f} values/sec)\")\n", + " return elapsed\n", + "\n", + "# On the slave side, you would read incoming data:\n", + "# def slave_receive_data(soc_slave, num_values=100):\n", + "# data = []\n", + "# for i in range(num_values):\n", + "# data.append(soc_slave.xcom_0.mem)\n", + "# return data\n", + "\n", + "print(\"Master-to-slave communication functions defined.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 8. Loopback Testing\n", + "\n", + "Loopback testing validates XCOM functionality by sending data to the same board (self-communication). This is useful for debugging without multiple boards." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Loopback test: write to self\n", + "def xcom_loopback_test(soc, num_transfers=1000):\n", + " \"\"\"\n", + " Perform XCOM loopback test by writing to self.\n", + " Returns list of received data and measured latency.\n", + " \"\"\"\n", + " dest = 2 # Send to self (using local board ID)\n", + " \n", + " # Configure XCOM for loopback\n", + " soc.xcom_0.xcom_cfg = 2 + 0x100 # Loopback mode\n", + " \n", + " # Clear destination memory\n", + " soc.xcom_0.run_cmd(soc.xcom_0.opcodes['XCOM_WRITE_MEM'], dest, 0)\n", + " \n", + " data_in = []\n", + " start_time = time.time()\n", + " \n", + " for i in range(1, num_transfers):\n", + " # Send 16-bit value\n", + " soc.xcom_0.run_cmd(soc.xcom_0.opcodes['XCOM_SEND_16BIT_2'], dest, i)\n", + " \n", + " # Wait for data to be received\n", + " while soc.xcom_0.mem == 0:\n", + " pass\n", + " \n", + " data_in.append(soc.xcom_0.mem)\n", + " \n", + " # Verify data integrity\n", + " if soc.xcom_0.mem != i:\n", + " print(f\"Data mismatch at i={i}: sent {i}, received {soc.xcom_0.mem}\")\n", + " \n", + " # Clear for next transfer\n", + " soc.xcom_0.run_cmd(soc.xcom_0.opcodes['XCOM_WRITE_MEM'], dest, 0)\n", + " \n", + " elapsed = time.time() - start_time\n", + " return data_in, elapsed\n", + "\n", + "# Run loopback test\n", + "print(\"Running XCOM loopback test...\")\n", + "try:\n", + " data_received, elapsed_time = xcom_loopback_test(soc, num_transfers=500)\n", + "\n", + " print(f\"\\nLoopback test complete.\")\n", + " print(f\"Elapsed time: {elapsed_time:.3f}s\")\n", + " print(f\"Transfers: {len(data_received)}\")\n", + " if len(data_received) > 0:\n", + " print(f\"Average latency per transfer: {elapsed_time/len(data_received)*1000:.3f} ms\")\n", + " \n", + " # Plot received data to verify ramp pattern\n", + " plt.figure(figsize=(12, 6))\n", + " if len(data_received) > 100:\n", + " plt.plot(data_received[0:100], '.-')\n", + " else:\n", + " plt.plot(data_received, '.-')\n", + " plt.xlabel('Transfer Number')\n", + " plt.ylabel('Received Value')\n", + " plt.title('XCOM Loopback Test - Received Data')\n", + " plt.grid(True)\n", + " plt.show()\n", + "except Exception as e:\n", + " print(f\"Loopback test failed: {e}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 9. Latency Measurement\n", + "\n", + "XCOM provides deterministic, low-latency communication. Precise latency can be measured using the tProc's absolute time counter." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Assembly program to measure XCOM round-trip latency\n", + "latency_measure_asm = \"\"\"\n", + "// XCOM Latency Measurement Program\n", + "// Measures round-trip latency by timing a send-receive cycle\n", + "\n", + "// Initialize registers\n", + "REG_WR r1 imm #1\n", + "REG_WR r2 imm #2 // Destination board ID\n", + "REG_WR r3 imm #3\n", + "REG_WR r4 imm #4\n", + "REG_WR r5 imm #5\n", + "REG_WR r10 imm #0 // DMEM pointer for data storage\n", + "\n", + "// Write some zeros to DMEM\n", + "DMEM_WR [r10] imm #0\n", + "DMEM_WR [r10 + &1] imm #0\n", + "DMEM_WR [r10 + &2] imm #0\n", + "DMEM_WR [r10 + &3] imm #0\n", + "DMEM_WR [r10 + &4] imm #0\n", + "DMEM_WR [r10 + &5] imm #0\n", + "\n", + "// Clear XCOM flag\n", + "REG_WR s_ctrl imm ctrl_csf_qpa\n", + "\n", + "LOOP:\n", + " // Record start time\n", + " REG_WR r12 op -op(s_usr_time)\n", + " \n", + " // Send data via XCOM\n", + " WAIT qpa_rdy\n", + " PA 6 r2 r6 // XCOM QCTRL operation\n", + " WAIT qpa_dt\n", + " \n", + " // Wait for response (flag from destination)\n", + " WAIT qpa_rdy\n", + " PA 0 r2 // Clear flag\n", + " WAIT qpa_dt\n", + " \n", + " // Record end time\n", + " REG_WR r13 op -op(s_usr_time)\n", + " \n", + " // Store delta time in DMEM\n", + " DMEM_WR [r10] op -op(r13 - r12)\n", + " \n", + " // Increment pointer and data\n", + " REG_WR r6 op -op(r6 + #1)\n", + " REG_WR r10 op -op(r10 + #1)\n", + " \n", + " // Loop counter\n", + " REG_WR r11 op -op(r11 - #1) -uf\n", + " JUMP LOOP -if(NZ)\n", + "\n", + ".END\n", + "\"\"\"\n", + "\n", + "print(\"Latency measurement program ready.\")\n", + "print(\"Run this on the master board to measure XCOM round-trip latency.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 9.1 Analyzing Latency Data\n", + "\n", + "After running the latency measurement program, analyze the collected timing data." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Example: Reading latency data from DMEM after tProc execution\n", + "def read_latency_data(soc, num_samples=100):\n", + " \"\"\"Read latency measurement data from tProc DMEM.\"\"\"\n", + " delta_times = []\n", + " \n", + " for i in range(num_samples):\n", + " # Read from DMEM (addresses 0, 1, 2, ...)\n", + " # Method name may vary based on firmware\n", + " # delta = soc.qick_processor_0.single_read(2, i)\n", + " delta_times.append(0) # Placeholder\n", + " \n", + " return delta_times\n", + "\n", + "print(\"Latency data analysis functions defined.\")\n", + "print(\"\\nAfter running the tProc program, you would analyze data with:\")\n", + "print(\" delta_times = read_latency_data(soc, num_samples=100)\")\n", + "print(\" plt.hist(delta_times, bins=50)\")\n", + "print(\" print(f'Average latency: {np.mean(delta_times)} cycles')\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 10. Using Flags for Synchronization\n", + "\n", + "XCOM flags provide a fast, single-bit signaling mechanism between boards. They are useful for:\n", + "- Triggering actions on slave boards\n", + "- Synchronizing state machines across boards\n", + "- Implementing token ring or handshake protocols" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Set flag on another board\n", + "def set_remote_flag(soc, dest_board_id):\n", + " \"\"\"Set the flag on a remote board.\"\"\"\n", + " print(f\"Setting flag on board {dest_board_id}...\")\n", + " soc.xcom_0.set_flag(dest_board_id)\n", + " print(\"Flag set.\")\n", + "\n", + "# Clear flag on another board\n", + "def clear_remote_flag(soc, dest_board_id):\n", + " \"\"\"Clear the flag on a remote board.\"\"\"\n", + " print(f\"Clearing flag on board {dest_board_id}...\")\n", + " soc.xcom_0.clear_flag(dest_board_id)\n", + " print(\"Flag cleared.\")\n", + "\n", + "# Check local flag status\n", + "def check_local_flag(soc):\n", + " \"\"\"Check the status of the local flag.\"\"\"\n", + " flag_status = soc.xcom_0.flag\n", + " print(f\"Local flag: {flag_status}\")\n", + " return flag_status\n", + "\n", + "# From tProc, you can wait for a flag using WAIT instruction\n", + "# WAIT qpa_rdy\n", + "# PA 0 r2 # Check/clear flag\n", + "# WAIT qpa_dt\n", + "\n", + "print(\"Flag operations defined.\")\n", + "print(\"\\nExample usage:\")\n", + "print(\" set_remote_flag(soc_master, slave_id)\")\n", + "print(\" check_local_flag(soc_slave)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 11. Absolute Clock Synchronization\n", + "\n", + "One of XCOM's most powerful features is **absolute clock synchronization** across all boards. The master can broadcast reset and start commands to align all tProc absolute time counters.\n", + "\n", + "### 11.1 Synchronization Protocol\n", + "\n", + "1. **Frequency synchronization**: All boards share the same external reference clock (e.g., 100 MHz rubidium)\n", + "2. **Phase synchronization**: PLLs configured in nested zero-delay mode\n", + "3. **DAC/ADC alignment**: Multi-tile sync (MTS) calibration\n", + "4. **Absolute time alignment**: Master broadcasts RESET and START commands" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Master broadcasts reset to all boards\n", + "def broadcast_reset(soc_master):\n", + " \"\"\"Broadcast absolute clock reset to all boards.\"\"\"\n", + " print(\"Broadcasting RESET command to all boards...\")\n", + " \n", + " # Use XCOM_QRST_SYNC opcode to broadcast reset\n", + " soc_master.xcom_0.run_cmd(soc_master.xcom_0.opcodes['XCOM_QRST_SYNC'], 0, 0)\n", + " time.sleep(0.1)\n", + " print(\"RESET broadcast complete.\")\n", + "\n", + "# Master broadcasts start to all boards\n", + "def broadcast_start(soc_master):\n", + " \"\"\"Broadcast absolute clock start to all boards.\"\"\"\n", + " print(\"Broadcasting START command to all boards...\")\n", + " \n", + " # Use XCOM_QCTRL with appropriate parameters to start\n", + " soc_master.xcom_0.run_cmd(soc_master.xcom_0.opcodes['XCOM_QCTRL'], 4, 6) # proc_start\n", + " time.sleep(0.1)\n", + " print(\"START broadcast complete.\")\n", + "\n", + "# Verify synchronization\n", + "def verify_sync(soc_board, expected_time=None):\n", + " \"\"\"Read absolute time from tProc to verify sync.\"\"\"\n", + " # Read absolute time from tProc (address depends on firmware)\n", + " # This is a placeholder - actual register address may vary\n", + " # abs_time = soc_board.qick_processor_0.single_read(2, 0)\n", + " abs_time = 0 # Placeholder\n", + " print(f\"Board absolute time: {abs_time}\")\n", + " return abs_time\n", + "\n", + "print(\"Synchronization functions defined.\")\n", + "print(\"\\nTypical synchronization sequence:\")\n", + "print(\" 1. broadcast_reset(soc_master) # Reset all absolute clocks\")\n", + "print(\" 2. time.sleep(0.1)\")\n", + "print(\" 3. broadcast_start(soc_master) # Start all absolute clocks\")\n", + "print(\" 4. verify_sync(soc_master)\")\n", + "print(\" 5. verify_sync(soc_slave1) # Should show same value\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 12. Debugging XCOM\n", + "\n", + "XCOM provides several debugging registers to help diagnose issues." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def diagnose_xcom(soc):\n", + " \"\"\"Run comprehensive XCOM diagnostics.\"\"\"\n", + " print(\"=\" * 60)\n", + " print(\"XCOM DIAGNOSTICS\")\n", + " print(\"=\" * 60)\n", + " \n", + " # Check XCOM presence\n", + " if not hasattr(soc, 'xcom_0'):\n", + " print(\"❌ XCOM not found! Check firmware bitstream.\")\n", + " return False\n", + " print(\"✅ XCOM found\")\n", + " \n", + " # Print status register\n", + " print(\"\\n--- Status Register ---\")\n", + " soc.xcom_0.print_status()\n", + " \n", + " # Print debug register\n", + " print(\"\\n--- Debug Register ---\")\n", + " soc.xcom_0.print_debug()\n", + " \n", + " # Print all registers\n", + " print(\"\\n--- All Registers ---\")\n", + " soc.xcom_0.print_axi_regs()\n", + " \n", + " # Test basic read/write\n", + " print(\"\\n--- Basic Read/Write Test ---\")\n", + " test_addr = 5\n", + " test_value = 0x12345678\n", + " \n", + " try:\n", + " soc.xcom_0.axi_addr = test_addr\n", + " original = soc.xcom_0.mem\n", + " soc.xcom_0.mem = test_value\n", + " readback = soc.xcom_0.mem\n", + " soc.xcom_0.mem = original # Restore\n", + " \n", + " if readback == test_value:\n", + " print(f\"✅ Memory write/read: wrote 0x{test_value:08X}, read 0x{readback:08X}\")\n", + " else:\n", + " print(f\"❌ Memory mismatch: wrote 0x{test_value:08X}, read 0x{readback:08X}\")\n", + " except Exception as e:\n", + " print(f\"❌ Memory test failed: {e}\")\n", + " \n", + " # Test loopback (if configured)\n", + " print(\"\\n--- Loopback Test ---\")\n", + " try:\n", + " data, elapsed = xcom_loopback_test(soc, num_transfers=10)\n", + " if len(data) == 9 and all(data[i] == i+1 for i in range(9)):\n", + " print(f\"✅ Loopback test passed ({len(data)} transfers)\")\n", + " else:\n", + " print(f\"⚠️ Loopback test had {len(data)} transfers, expected 9\")\n", + " except Exception as e:\n", + " print(f\"❌ Loopback test failed: {e}\")\n", + " \n", + " print(\"\\n\" + \"=\" * 60)\n", + " return True\n", + "\n", + "# Run diagnostics\n", + "diagnose_xcom(soc)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 13. Common Issues and Troubleshooting\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"\"\"\n", + "╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════╗\n", + "║ XCOM TROUBLESHOOTING GUIDE ║\n", + "╠══════════════════════════════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ ║\n", + "║ Issue │ Likely Cause │ Solution ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────║\n", + "║ XCOM not detected │ Wrong firmware │ Use bitstream with XCOM IP ║\n", + "║ │ Missing FMC board │ Install XCOM transceiver board ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────║\n", + "║ AUTO_ID fails │ No external hub connected │ Connect all boards to XCOM hub ║\n", + "║ │ Cable mismatch │ Use matched-length LVDS cables ║\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────║\n", + "║ High latency (>200 ns) │ XCOM clock too low │ Increase LVDS clock (up to 312.9 MHz) │\n", + "║ │ Software overhead │ Use tProc instead of Python for timing │\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────║\n", + "║ Data corruption │ LVDS signal integrity │ Check cable quality and length │\n", + "║ │ Clock skew │ Run MTS calibration │\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────║\n", + "║ Flag not received │ Wrong destination ID │ Verify board IDs with auto_id() │\n", + "║ │ Flag not cleared │ Always clear flag after receipt │\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────║\n", + "║ tProc XCOM commands fail │ Peripheral not ready │ Add WAIT qpa_rdy before PA │\n", + "║ │ Incorrect PA configuration │ Verify cfg register values │\n", + "║ ──────────────────────────────┼─────────────────────────────────┼───────────────────────────────────────────║\n", + "║ Synchronization drift │ External clock not locked │ Verify PLL lock status │\n", + "║ │ Missing MTS calibration │ Run init_tile_sync() and sync_tiles() │\n", + "║ ║\n", + "╠══════════════════════════════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ QUICK DIAGNOSTIC COMMANDS ║\n", + "╠══════════════════════════════════════════════════════════════════════════════════════════════════════════════╣\n", + "║ ║\n", + "║ # Check if XCOM is present ║\n", + "║ hasattr(soc, 'xcom_0') ║\n", + "║ ║\n", + "║ # Print all XCOM registers ║\n", + "║ soc.xcom_0.print_axi_regs() ║\n", + "║ ║\n", + "║ # Check XCOM status ║\n", + "║ soc.xcom_0.print_status() ║\n", + "║ ║\n", + "║ # Run full diagnostics ║\n", + "║ diagnose_xcom(soc) ║\n", + "║ ║\n", + "╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════╝\n", + "\"\"\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 14. Summary\n", + "\n", + "You have learned:\n", + "\n", + "1. **XCOM Architecture**: Full mesh network for multi-board synchronization and communication\n", + "2. **Hardware Requirements**: FMC transceiver boards and external hub for 5-15 boards\n", + "3. **Network Configuration**: AUTO_ID, set_local_id, master/slave roles\n", + "4. **Data Transfer**: Sending 8/16/32-bit data between boards with deterministic latency\n", + "5. **tProc Integration**: Using PA instruction for real-time XCOM access\n", + "6. **Flags**: Fast single-bit signaling for synchronization\n", + "7. **Absolute Clock Sync**: Broadcasting RESET/START to align all tProcs\n", + "8. **Debugging**: Status registers, diagnostics, troubleshooting\n", + "\n", + "### Key Takeaways\n", + "\n", + "- XCOM enables <100 ps skew and 186 ns deterministic latency between boards\n", + "- Each board has a dedicated Tx channel; all boards listen on all Rx channels\n", + "- The master board can synchronize absolute clocks across the entire network\n", + "- tProc integration allows real-time XCOM communication without software overhead\n", + "- Always run MTS calibration and verify external clock before using XCOM\n", + "\n", + "### Next Steps\n", + "\n", + "- For simpler multi-board synchronization (external clock + external start), see [`10_Multi_Board_Synchronization.ipynb`](./10_Multi_Board_Synchronization.ipynb)\n", + "- Proceed to explore other advanced topics\n", + "- For more information, refer to the XCOM paper (arXiv:2603.18977v1)\n", + "- Check the QICK firmware documentation for XCOM IP details\n", + "\n", + "## References\n", + "\n", + "- For detailed XCOM documentation, see [XCOM Overview](../topics/xcom.rst)\n", + "- XCOM Command Reference: [Command Reference](../topics/XCOM-commands.rst)\n", + "- XCOM Paper: [arXiv:2603.18977v1](https://arxiv.org/abs/2603.18977v1)\n", + "- QICK XCOM driver: `qick.ip.QICK_Xcom`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.8.0" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/source/tutorials/README.md b/docs/source/tutorials/README.md new file mode 100644 index 000000000..526204ce8 --- /dev/null +++ b/docs/source/tutorials/README.md @@ -0,0 +1,112 @@ +# QICK Tutorial Notebooks + +This directory contains Jupyter notebooks that introduce the QICK framework and the tProc v2. + +## Prerequisites + +- QICK installed on RFSoC board or remote PC +- Firmware bitstream file (`.bit`) for your board +- Jupyter notebook/lab + +## Notebooks + +### Basic (00–05) + +| # | Notebook | Description | +|:-|:---|:---| +| 00 | `00_Getting_Started.ipynb` | Connect to the board, inspect hardware configuration | +| 01 | `01_Basic_Sequencing.ipynb` | Define pulses, create sequences, acquire data | +| 02 | `02_Parameter_Sweeps.ipynb` | 1D and 2D parameter sweeps | +| 03 | `03_Advanced_Timing.ipynb` | `delay` vs `wait`, auto-timing, avoiding collisions | +| 04 | `04_Real_Time_Feedback.ipynb` | Conditional pulses, active reset, thresholding | +| 05 | `05_Dynamic_Parameters_Subroutines.ipynb` | Virtual-Z gates, subroutines, dynamic updates | + +### Intermediate (06–09) + +| # | Notebook | Description | +|:-|:---|:---| +| 06 | `06_Generators_And_Readouts.ipynb` | Basic waveform generators, readout resonators, I/Q mixing | +| 07 | `07_Advanced_Generators_And_Readouts.ipynb` | Muxed generators, PFB readout, dynamic readouts, fast dynamic readout, electrical delay calibration, IQ offsets, performance benchmarks | +| 08 | `08_Hardware_Buffers.ipynb` | DDR4 and MR buffers, data capture | +| 09 | `09_Appendix_Tips_And_Limits.ipynb` | Common errors, limits, debugging tips | + +### Advanced (10–14) + +| # | Notebook | Description | +|:-|:---|:---| +| 10 | `10_Multi_Board_Synchronization.ipynb` | Synchronize multiple boards using external clock and external start signals | +| 11 | `11_Streaming_And_RealTime_Processing.ipynb` | IQ streaming, on-FPGA averaging, real-time decimation | +| 12 | `12_DSP_Blocks_And_Correlators.ipynb` | FIR filters, DDS tuning, hardware correlators | +| 13 | `13_Custom_Firmware_Integration.ipynb` | Adding custom Verilog/VHDL, AXI-lite interface, rebuilding | +| 14 | `14_XCOM_Network_Synchronization.ipynb` | Full mesh network for multi-board synchronization and low-latency communication (requires FMC transceiver board) | + +## Usage + +1. Copy these notebooks to your RFSoC board (or run them directly from this location) +2. Start Jupyter: `jupyter notebook` or `jupyter lab` +3. Open the desired notebook +4. **IMPORTANT**: Change the `BITSTREAM_PATH` variable in each notebook to point to your firmware file +5. Run cells sequentially + +## Remote Execution + +For remote execution (e.g., from a PC), you'll need to start the QICK proxy server on the board first: + +```bash +python -m qick.pyro +``` + +Then in your notebook, use: + +```python +from qick.pyro import make_proxy +soc = make_proxy("board_ip_address") +``` +## Common Setup Cell (copy this to any notebook) + +```python +# Configuration +BITSTREAM_PATH = "/path/to/your/firmware.bit" # ← CHANGE THIS + +# Optional: remote execution +USE_PROXY = False +PROXY_IP = "192.168.1.100" + +# Connection +from qick import QickSoc +import numpy as np +import matplotlib.pyplot as plt + +if USE_PROXY: + from qick.pyro import make_proxy + soc = make_proxy(PROXY_IP) + print(f"Connected to proxy at {PROXY_IP}") +else: + soc = QickSoc(bitfile=BITSTREAM_PATH) + print("Connected directly to RFSoC") + +print(f"Firmware: {soc.get_cfg()['fw_version']}") +print(f"tProc cores: {soc.num_tprocs}") +``` + +## Notes + +* Notebooks 00–09 are self-contained and work on any QICK setup + +* Notebooks 10–14 require additional hardware resources (multi-board, streaming, DSP48) + +* Notebook 13 requires a licensed Vivado installation for custom firmware compilation + +* Notebook 14 (XCOM) requires additional hardware: FMC transceiver board and external hub + +## Troubleshooting + +If you see "Bitstream not found", check `BITSTREAM_PATH` + +If tProc commands fail, try `soc.reset_gens()` and `soc.reset_adcs()` + +For proxy connection issues, verify the board IP and that the proxy is running + +If no signal in readout, check DAC→ADC loopback cables, verify `gen_ch` is correct + +Phase rotates with frequency, run electrical delay calibration (see [Notebook 07](./07_Advanced_Generators_And_Readouts.ipynb)) \ No newline at end of file diff --git a/docs/topics/asmv1_cheatsheet.rst b/docs/topics/asmv1_cheatsheet.rst deleted file mode 100644 index 252b66875..000000000 --- a/docs/topics/asmv1_cheatsheet.rst +++ /dev/null @@ -1,58 +0,0 @@ -tProc v1 ASM cheatsheet -======================= - -.. list-table:: - :widths: 50 50 - :header-rows: 1 - - * - Python calls - - - * - ``soc.tproc.single_write(addr=imm, data=variable)`` - - writes the value ``variable`` to the data memory address ``imm``. - -.. list-table:: - :widths: 50 50 - :header-rows: 1 - - * - ASM_Program calls - - - * - ``p.memri(p, r, imm, 'comment')`` - - reads the data memory at the address specified by ``imm`` and writes the result into page ``p``, register ``r``. - * - ``p.regwi(p,r,value)`` - - writes the ``value`` to page ``p``, register ``r``. - * - ``p.bitwi(p, rDst, rSrc, operation, value)`` - - performs the bitwise ``operation`` on the contents of page ``p``, register ``rSrc`` and ``value`` and writes the result in page ``p``, register ``rDst``. ``rSrc`` and ``rDst`` may be the same or different. - * - ``p.bitw(p, rDst, rSrc1, operation, rSrc2`` - - performs the bitwise ``operation`` on two source registers (``rSrc1`` and ``rSrc2``) and puts the result in the destination register ``rDst``, where all three registers are on the same page ``p``. - * - ``p.seti(channel, p, rSrc, time)`` - - takes the value at page ``p``, register ``rSrc`` and sends it to ``channel`` that the specified ``time``. - * - ``p.label(labelName)`` - - marks this location in the program, for use by the ``loopz`` and ``condj`` commands. - * - ``p.set(channel, p, ra, rb,rc,rd,re,time)`` - - sends the values on page ``p`` registers ``ra``, ``rb``, ``rc``, ``rd``, ``re`` to ``channel`` at ``time``. The registers ``ra`` through ``re`` contain, in order, 16-bit values of frequency, phase, address, gain, and ( ``nsamp`` , ``outsel`` , ``mode`` , ``stdysel`` ). - * - ``p.sync(p,r)`` - - synchronizes the internal time offset to the value specified by page ``p``,register ``r``. - * - ``p.synci(p,timeOffset)`` - - synchronizes the internal time offset by ``timeOffset``. - -.. list-table:: - :widths: 50 50 - :header-rows: 1 - - * - QickProgram bitwise operations - - - * - ``<<`` - - shifts bits left by ``value`` bits, ignores ``rSrc`` - * - ``|`` - - or - * - ``&`` - - and - * - ``^`` - - exclusive or - * - ``~`` - - not ``value``, ignores ``rSrc`` - -tProcessor register information -------------------------------- - -The tproc contains 8 pages of 32 registers each, making 256 registers in total. Each register is 32 bits wide. diff --git a/docs/topics/freq_matching.rst b/docs/topics/freq_matching.rst deleted file mode 100644 index f32b31c42..000000000 --- a/docs/topics/freq_matching.rst +++ /dev/null @@ -1,20 +0,0 @@ -How to ensure frequency matching -================================ - -Generators and readouts have different frequency units, and the frequencies used in the two systems must be exactly equal. -If they are not, there will be a small difference between the upconversion and downconversion frequencies - this will manifest as a sliding phase, and so you will not see a consistent phase between acquisitions. - -There are two ways to ensure frequency matching: - -* When converting a frequency to an integer value (often with :meth:`.QickConfig.freq2reg()` or :meth:`.AbsQickProgram.declare_readout()`), specify not only the channel you are configuring, but the channel you want to be frequency-matched to. -* Before doing any conversion, round the frequency to the closest frequency that is valid on both channels using :meth:`.QickConfig.adcfreq()`. - -Frequency-matching makes your frequency resolution worse, since the smallest possible frequency step is now the LCM of the two channels' frequency steps. -Usually this doesn't matter - O(10 Hz) resolution is ample for most applications - but you can disable frequency-matching by specifying None as the other channel. - -You may have a generator that does not itself drive any readouts, but needs to be phase-locked to a generator that does. -In this case you will want to frequency-match both generators to that readout, otherwise the two generators will have slightly different frequencies and you will have a sliding phase between them. - -If you have multiple generators (or readouts) of the same type and sampling frequency, it doesn't matter which you use to specify the matched channel. -In many QICK firmwares, all generator and readout channels are the same and it's OK to just use ch 0 for the matched channel. -But it's a good habit to do this consistently correctly. diff --git a/docs/topics/index.rst b/docs/topics/index.rst deleted file mode 100644 index 068111449..000000000 --- a/docs/topics/index.rst +++ /dev/null @@ -1,14 +0,0 @@ -Specific topics -=============== - -.. toctree:: - :maxdepth: 1 - - asmv1_cheatsheet - timing - freq_matching - playing_pulses - gen_config - units - changing_fs - reference_clock diff --git a/docs/topics/playing_pulses.rst b/docs/topics/playing_pulses.rst deleted file mode 100644 index 4e9ca76e9..000000000 --- a/docs/topics/playing_pulses.rst +++ /dev/null @@ -1,41 +0,0 @@ -How to play pulses -================== - -There are three steps to playing a pulse: - -Loading a waveform ------------------- - -(You skip this step for rectangular "const" pulses, which have no envelope.) - -Each signal generator has an internal waveform memory, which stores the I/Q data for the pulse envelope. -Multiple waveforms can be stored in the same signal generator, and a single waveform can be used for different pulses (e.g. a Gaussian waveform can be used for Gaussian pulses and the ramp-up/ramp-down of flat-top pulses with different flat-top duration, each with its own gain and carrier frequency). - -:meth:`.AbsQickProgram.add_envelope()` writes an arbitrary waveform to the specified channel's waveform memory. -:meth:`.AbsQickProgram.add_gauss()`, :meth:`.AbsQickProgram.add_triangle()`, and :meth:`.AbsQickProgram.add_DRAG()` write commonly-used standard pulse waveforms, with duration units of fabric clock cycles. The name is used in the next step. - -Setting registers ------------------ - -There are a lot of parameters that need to be specified when playing a pulse - more than can be specified inline in a tProcessor instruction. -So all the parameters must be written to registers first, and when we fire the pulse we just tell the tProcessor which registers to read. - -:meth:`.QickProgram.set_pulse_registers()` writes the settings for a pulse to registers. -All arguments to this method must be integers in the native units of the signal generator. -This can happen immediately before you fire the pulse, but if a signal generator is only used for one type of pulse you will save time for the tProcessor by setting registers in initialization, before the program loop. -If you have some parameters that change from pulse to pulse, and some that never change, you can write the fixed parameters in initialization using :meth:`.QickProgram.default_pulse_registers()` and the varying parameters in the body with :meth:`.QickProgram.set_pulse_registers()`. - -If you want to modify pulse parameters on the fly (for example, you might want to sweep the frequency of the qubit drive pulse), you will set the registers in two steps (you can see an example in the demo :repofile:`qick_demos/02_Sweeping_variables.ipynb` ): - -First, use :meth:`.QickProgram.set_pulse_registers()` to write initial values for all parameters. You could do this in initialization, or right before the following step. -Second, overwrite the register(s) you want to update. -You need to get the page and address of the register using :meth:`.QickProgram.ch_page()` and :meth:`.QickProgram.sreg()`. -Then you can use assembly instructions to change the value of that register. - -Firing the pulse ----------------- - -:meth:`.QickProgram.pulse()` fires a pulse on the specified channel at the specified time, using whatever values are loaded in the registers. - -Often you will want to trigger the readout at the same time: :meth:`.QickProgram.measure()` is a wrapper around :meth:`.QickProgram.trigger()` and :meth:`.QickProgram.pulse()`. -But it's good to remember and understand the building blocks inside this wrapper. diff --git a/docs/topics/timing.rst b/docs/topics/timing.rst deleted file mode 100644 index 686079323..000000000 --- a/docs/topics/timing.rst +++ /dev/null @@ -1,62 +0,0 @@ -Timing -====== - -* Every generator contains a timed FIFO queue. - There is only one master clock time `t_master`, which is shared by all timed queues. - - * Treat :meth:`.QickProgram.trigger()` as a generator channel, i.e. equivalent to :meth:`.QickProgram.pulse()` in terms of clocks. - -* The tproc executes commands as soon as possible, meaning it has no concept of the master time (aside from wait commands, explained later). - It only cares about what point it is at in your code. - There is a master time offset `t_off`, which is incremented by sync commands. - When executed by the tproc, ``trigger(t)`` and ``pulse(t)`` commands are appended to the appropriate queue with a timestamp of ``t_off + t``. - -* A generator plays pulses in the order received. - It waits to play each pulse until the previous pulse is complete and the master clock time equals (or exceeds) the command timestamp. - -* ``pulse(ch,t)`` will play the pulse at ``t`` relative to the clock as defined by the sync command that has been most recently executed by the tproc, UNLESS it is delayed by a wait command (the generator can't play a pulse before the tproc executes the command) or another pulse command (the generator can't cut one pulse short to play the next one). - In that case, it will play at time ``t`` or at the end of the wait time/previous pulse, whatever is latest. - - * To make life easier, you can just always call ``pulse(ch, t=0)``, which will just play the pulse at the next earliest possible time. Then insert simple waits between pulses using ``sync_all(t=wait_time)``. - -* wait commands pause the tproc (i.e. pauses execution of commands). - They do not affect the master time. - Any commands lower down in your code, even if scheduled for some time (defined by the master time) during the wait period, will execute, at the earliest, immediately after the end of the wait period. - - * wait commands are necessary to use with readout/data acquisition timing management, as the tproc does not know when pulses/readout finish and you need to force it to wait for readout to finish. - In other words, you should have a wait at the end of a loop (or the tproc will tell the software to read data from the buffer too soon), or before a ``read`` command (e.g. for feedback). - `This is the only reason to use wait commands.` - - * ``waiti(t)`` is the generic form of wait, which pauses the tproc until the master clock time equals ``t_off + t``. Note ``waiti`` has a channel argument, but the channel argument does nothing! - - * :meth:`.QickProgram.wait_all()` calculates the end of all readout pulses and waits until that time + ``t``. - -* sync commands increment the master time offset (used by all gen channels). - The effect is to push back the play time of subsequent commands by that increment. - - * ``synci(t)`` is the generic form of sync. - - * The safer version :meth:`.QickProgram.sync_all()` calculates the end of the last pulse played + ``t``, and sets the master time offset to that value. - -How to avoid timing problems ----------------------------- - -Timed instructions are executed in two steps: first when the control core of the tProcessor pushes the instruction into the timed queue, and second when the instruction pops off the timed queue. - -* The control core executes all instructions in order and (except ``wait``/``waiti``) as quickly as possible. - If you have a non-timed instruction with external effects, it will generally execute before the timed instructions before and after it. - Specifically, programs (like the AveragerProgram framework we're using here) typically use ``memwi`` to update a data counter, and then read that counter to know how many data samples to get from the buffers - if the ``memwi`` happens before the readout is triggered or completed, you will read invalid data. - -* If the instruction is pushed later than the specified time, it will execute later than specified - this can lead to variations in the relative timing of pulses and readout windows. You are responsible for keeping the control core running ahead of the instruction times. - -Things you should do in your programs: - -* Your initialization should contain a ``synci`` instruction which gives the tProcessor time to get ahead of the clock. - -* Put a :meth:`.QickProgram.sync_all()` somewhere in your loop body, probably at the end. This ensures that you don't have pulses or readouts that exceed the loop length. - -* Put a ``waiti`` instruction after the last readout in your loop body, to make sure the tProcessor doesn't prematurely update the data counter. - -* Follow the ``waiti`` with a ``synci`` that exceeds the ``waiti``, to allow the tProcessor to get ahead of the clock. - -* The last three points are automatically addressed if the last timed instruction in your loop body is a :meth:`.QickProgram.measure()` instruction that specifies ``wait=True`` and a nonzero ``syncdelay``. diff --git a/docs/topics/units.rst b/docs/topics/units.rst deleted file mode 100644 index 1bff8ed52..000000000 --- a/docs/topics/units.rst +++ /dev/null @@ -1,13 +0,0 @@ -Time units -========== - -Time durations are generally specified in units of clock cycles. -The relevant clocks are the tProcessor clock and the fabric clocks of the generators and readouts. -In general these can all be different (and can even vary among generators or readouts). - -For convenience, the :meth:`.QickConfig.us2cycles()` and :meth:`.QickConfig.cycles2us()` methods will convert between floating-point times and integer cycles. -You should be careful to specify which clock you are using, and set the appropriate parameter in :meth:`.QickConfig.us2cycles()`: - -Pulse parameters (the length parameter to :meth:`.QickProgram.set_pulse_registers()`, the length and sigma parameters to :meth:`.AbsQickProgram.add_gauss()`) use the generator clock and you should specify ``gen_ch``. -Readout parameters (the length parameter to :meth:`.AbsQickProgram.declare_readout()`) use the readout clock and you should specify ``ro_ch``. -All other values will use the tProc clock. This includes ``sync`` and ``wait`` commands, and any sort of delay (``t``, ``adc_trig_offset``). Don't use a channel ID parameter. From 72473f4b4e1f53105c857a5fd017d19821ce2f60 Mon Sep 17 00:00:00 2001 From: "QICK actions [bot]" <129547417+qickbot@users.noreply.github.com> Date: Fri, 4 Sep 2026 21:50:00 +0000 Subject: [PATCH 08/23] update version --- qick_lib/qick/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qick_lib/qick/VERSION b/qick_lib/qick/VERSION index 15c5c1356..b82de4610 100644 --- a/qick_lib/qick/VERSION +++ b/qick_lib/qick/VERSION @@ -1 +1 @@ -0.2.422 +0.2.430 From 3599e259002ad84490e528aab176de8f565e3e6f Mon Sep 17 00:00:00 2001 From: Horacio Arnaldi Date: Sat, 5 Sep 2026 14:25:40 -0500 Subject: [PATCH 09/23] docs: add tProc v1->v2 migration guide and community example-code page Content originally proposed in PR #412 by Jay Chien against the old docs/*.rst tree (now superseded by docs/source/, so that PR no longer applies cleanly). Ports it into the current docs/source/topics/ tree, crediting the original author, and verifies every API name used (add_loop, QickSweep1D, get_pulse_param, get_time_param, delay/ delay_auto/wait_auto, AveragerProgramV2.acquire) against qick.asm_v2 and qick.qick_asm. Also fixes the example-code page's Markdown-style headings/links, which were invalid in an .rst file. Verified with a full local sphinx-build: same pre-existing 26-warning baseline, no new warnings from either page. --- docs/source/topics/example_code.rst | 23 ++++ docs/source/topics/index.rst | 10 ++ docs/source/topics/tprocv2_migration.rst | 138 +++++++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 docs/source/topics/example_code.rst create mode 100644 docs/source/topics/tprocv2_migration.rst diff --git a/docs/source/topics/example_code.rst b/docs/source/topics/example_code.rst new file mode 100644 index 000000000..184636cca --- /dev/null +++ b/docs/source/topics/example_code.rst @@ -0,0 +1,23 @@ +Example code from the community +================================= + +.. note:: + List originally contributed by `Jay Chien `_ + (`PR #412 `_). + +Beyond the tutorials in :doc:`tutorials`, QICK collaborators have shared +larger example codebases built on top of QICK. These are useful as reference +for structuring real measurement code, but are maintained independently of +this repository and are not guaranteed to track the latest QICK release. + +Built on tProc v1 +----------------- + +* `IEEE Quantum Week 2023 QICK tutorial `_ +* `Connie Miao, Schuster Lab `_ +* `Chao Zhou, Hatlab `_ + +Built on tProc v2 +----------------- + +* `Jay Chien, SQL Lab `_ diff --git a/docs/source/topics/index.rst b/docs/source/topics/index.rst index 7b2b89acd..2c8cee429 100644 --- a/docs/source/topics/index.rst +++ b/docs/source/topics/index.rst @@ -27,6 +27,8 @@ These topics assume you have completed the basic tutorials (00-05) and are famil asmv2_cheatsheet tutorials + tprocv2_migration + example_code .. toctree:: :maxdepth: 1 @@ -70,6 +72,12 @@ Topic Descriptions **tutorials** Link to the full Jupyter notebook tutorials. +**tprocv2_migration** + Short migration guide for tProc v1 users: hardware sweeps, timing calls, pulse playback, and units. + +**example_code** + Larger example codebases shared by QICK collaborators, for both tProc v1 and v2. + **xcom** XCOM: Full mesh network for multi-board synchronization and low-latency communication. Covers hardware requirements, communication protocol, command set, and Python interface. @@ -89,5 +97,7 @@ When to Use Each Topic - **Not sure whether to use `acquire` or `acquire_decimated`?** See :doc:`readout_modes` - **Using external clock?** Refer to :doc:`reference_clock` - **Writing assembly code?** Keep :doc:`asmv2_cheatsheet` handy +- **Coming from tProc v1?** Start with :doc:`tprocv2_migration` +- **Looking for full example experiments?** See :doc:`example_code` - **Synchronizing multiple boards?** Read :doc:`xcom` for the network-based solution - **Need XCOM command details?** See :doc:`XCOM-commands` for the complete command reference \ No newline at end of file diff --git a/docs/source/topics/tprocv2_migration.rst b/docs/source/topics/tprocv2_migration.rst new file mode 100644 index 000000000..840c3125d --- /dev/null +++ b/docs/source/topics/tprocv2_migration.rst @@ -0,0 +1,138 @@ +Migrating from tProc v1 +======================== + +.. note:: + Content originally contributed by `Jay Chien `_ + (`PR #412 `_), adapted here + for the current docs structure and verified against ``qick.asm_v2``. + +tProc v2 keeps the same basic role as tProc v1 — sequencing pulses, triggers, +readout windows, and feedback — but reorganizes both the firmware interface and +the Python programming model. This page is a short migration guide for users +who already know tProc v1 and want to understand the most important changes +before writing tProc v2 programs. For the full picture, see :doc:`playing_pulses`, +:doc:`timing`, and :doc:`units`. + +Hardware sweeps +---------------- + +In tProc v1 programs, hardware sweeps often required an ``update()`` method +with explicit register math. For example, a gain sweep might update the +generator's gain register with ``mathi()`` after each shot: + +.. code-block:: python + + class Program(RAveragerProgram): + def initialize(self): + self.q_rp = self.ch_page(self.cfg["qubit_ch"]) + self.r_gain = self.sreg(self.cfg["qubit_ch"], "gain") + + def body(self): + ... + + def update(self): + self.mathi(self.q_rp, self.r_gain, self.r_gain, "+", self.cfg["step"]) + + gain_list, avgi, avgq = prog.acquire(soc) + +tProc v2 provides higher-level sweep helpers. A program declares a loop with +:meth:`~.QickProgramV2.add_loop`, attaches a swept parameter to that loop with +:func:`~.QickSweep1D`, and later queries the compiled program for the actual +sweep points: + +.. code-block:: python + + class Program(AveragerProgramV2): + def _initialize(self, cfg): + self.add_loop("gainloop", cfg["steps"]) + self.add_pulse( + ch=cfg["qubit_ch"], + name="qubit_pulse", + style="const", + freq=cfg["freq"], + phase=0, + gain=QickSweep1D("gainloop", cfg["gain_start"], cfg["gain_stop"]), + length=cfg["length"], + ) + + def _body(self, cfg): + self.pulse(ch=cfg["qubit_ch"], name="qubit_pulse", t=0) + + iq_list = prog.acquire(soc, rounds=avg, progress=False) + gains = prog.get_pulse_param("qubit_pulse", "gain", as_array=True) + +Common swept parameters include frequency, length, time, and gain. For +frequency, length, and gain sweeps, use ``get_pulse_param()`` to query the +compiled sweep points: + +.. code-block:: python + + freqs = prog.get_pulse_param("qubit_pulse", "freq", as_array=True) + lengths = prog.get_pulse_param("qubit_pulse", "length", as_array=True) + gains = prog.get_pulse_param("qubit_pulse", "gain", as_array=True) + +For timing sweeps, tag the timed instruction (``delay``, ``delay_auto``, ...) +and use ``get_time_param()``: + +.. code-block:: python + + times = prog.get_time_param("time_tag", "t", as_array=True) + +Timing +------ + +In tProc v2, pulse and trigger times are written in user-facing units, usually +microseconds. The Python API converts these values to tProc timing-clock cycles +when the program is compiled. See :doc:`timing` for the underlying clock model. + +Some tProc v1 timing calls have renamed equivalents in ``QickProgramV2``: + +.. list-table:: + :header-rows: 1 + :widths: 30 30 40 + + * - tProc v1 + - tProc v2 + - Notes + * - ``sync_all()`` + - ``delay_auto()`` + - Advances the reference time to the end of the last pulse/readout, plus an optional margin. + * - ``synci(t)`` + - ``delay(t)`` + - Advances the reference time by a fixed amount, independent of pulse/readout end times. + * - (no direct v1 equivalent) + - ``wait_auto()`` / ``wait(t)`` + - Pauses execution without moving the reference time; see :doc:`timing`. + +Playing pulses +-------------- + +In tProc v1, pulse parameters were typically loaded into generator registers +right before playing a pulse. In tProc v2, pulse settings are stored as +waveforms in waveform memory ahead of time: a pulse can bundle one or more +waveforms, and ``pulse()`` just tells the generator which waveform-memory entry +to play. This makes it easy to define several pulses during initialization and +choose which one to play in the program body. See :doc:`playing_pulses` for the +full workflow. + +A typical tProc v2 program: + +* Declares the generator and readout channels (``declare_gen()``, ``declare_readout()``). +* Adds pulse definitions in ``_initialize()`` (``add_envelope()``, ``add_pulse()``). +* Plays those pulses in ``_body()`` with ``pulse()``. +* Uses ``trigger()`` and ``acquire()``/``acquire_decimated()`` when readout data is needed. + +Units +----- + +tProc v2 APIs generally use natural units instead of raw register values: + +* Times and pulse lengths are in microseconds. +* Frequencies are in MHz. +* Phases are in degrees. +* Gains are normalized values, usually from ``-1`` to ``1``. + +The compiler rounds these values to the nearest supported hardware +representation. To inspect the rounded values actually used by a compiled +program, use ``get_pulse_param()`` and ``get_time_param()``. See :doc:`units` +for the full reference. From 18bb820c2c9f0d377cbe750e9f656ead321dd489 Mon Sep 17 00:00:00 2001 From: Horacio Arnaldi Date: Sat, 5 Sep 2026 15:18:26 -0500 Subject: [PATCH 10/23] docs: default 'make html' to the project venv, ignore /.venv/ Plain 'make html' fell back to whatever sphinx-build is on PATH (system Sphinx, missing nbsphinx/myst-parser) since nothing pointed it at a venv with docs/requirements.txt installed. Default SPHINXBUILD to ../.venv/bin/sphinx-build when it exists, still overridable via 'make SPHINXBUILD=... html'. --- .gitignore | 3 +++ docs/Makefile | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5263f7ad1..eee2f0509 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,9 @@ __pycache__/ .installed.cfg *.egg +# Docs build venv (see docs/requirements.txt, docs/Makefile) +/.venv/ + # Distribution / packaging build/ dist/ diff --git a/docs/Makefile b/docs/Makefile index ecc450b60..57e92e5e0 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -3,7 +3,10 @@ # You can set these variables from the command line. SPHINXOPTS = -SPHINXBUILD = sphinx-build +# Defaults to the project venv (../.venv, see docs/requirements.txt) if it +# exists, so 'make html' works without manually activating it first. +# Override with 'make SPHINXBUILD=... html' to use a different interpreter/env. +SPHINXBUILD = $(if $(wildcard ../.venv/bin/sphinx-build),../.venv/bin/sphinx-build,sphinx-build) PAPER = BUILDDIR = _build From 0f9c201ad97583a202c1a7473b96c56483cdbe6d Mon Sep 17 00:00:00 2001 From: Horacio Arnaldi Date: Tue, 8 Sep 2026 10:14:35 -0500 Subject: [PATCH 11/23] docs: reorder index.rst for new users, add hand-drawn firmware diagrams Syncs qick_internal's fix-tprocv2-trm-docs work since the last update: - index.rst reordered for a new-user learning path: tutorials split into their existing Basic/Intermediate/Advanced tiers as separate sidebar captions, firmware overview promoted ahead of the deep tProc v2 TRM, and legacy tProc v1 pushed to its own clearly-marked tier at the end. - 14 hand-drawn circuitikz block diagrams (general firmware system diagram plus one per generator/readout/support core and tProc v2 itself), each verified against the real RTL, not auto-extracted or copied from memory. Sources and the `make tikz-diagrams` build live in qick_internal's firmware/fusesoc/ (private RTL infra); this repo gets the rendered SVGs. Verified with a full local sphinx-build: same pre-existing 26-warning baseline, diagrams and sidebar order confirmed in the built HTML. --- docs/source/firmware.rst | 9 + .../images/firmware/dyn_readout-blocks.svg | 493 ++++++ .../images/firmware/firmware-overview.svg | 471 ++++++ docs/source/images/firmware/kidsim-blocks.svg | 1002 ++++++++++++ .../images/firmware/mr_buffer_et-blocks.svg | 837 ++++++++++ .../images/firmware/readout_pfb_v2-blocks.svg | 791 ++++++++++ .../images/firmware/readout_pfb_v3-blocks.svg | 792 ++++++++++ .../images/firmware/readout_v2-blocks.svg | 882 +++++++++++ .../images/firmware/sg_int4_v2-blocks.svg | 516 +++++++ .../images/firmware/sg_mixmux8-blocks.svg | 815 ++++++++++ .../source/images/firmware/sg_mux8-blocks.svg | 750 +++++++++ docs/source/images/firmware/sg_v4-blocks.svg | 810 ++++++++++ docs/source/images/firmware/sg_v6-blocks.svg | 505 ++++++ .../images/firmware/support_cores-blocks.svg | 1185 ++++++++++++++ .../source/images/firmware/tprocv2-blocks.svg | 1363 +++++++++++++++++ docs/source/index.rst | 63 +- docs/source/kidsim.md | 11 + docs/source/mr_buffer_et.rst | 9 + docs/source/readout_dynamic.rst | 12 + docs/source/readout_pfb.rst | 19 + docs/source/readout_v2.rst | 13 + docs/source/sg_int4_v2.rst | 9 + docs/source/sg_mixmux8.rst | 10 + docs/source/sg_mux8.rst | 10 + docs/source/sg_v4.rst | 11 + docs/source/sg_v6.rst | 11 + docs/source/support_cores.rst | 7 + docs/source/tprocv2_trm.rst | 87 +- 28 files changed, 11408 insertions(+), 85 deletions(-) create mode 100644 docs/source/images/firmware/dyn_readout-blocks.svg create mode 100644 docs/source/images/firmware/firmware-overview.svg create mode 100644 docs/source/images/firmware/kidsim-blocks.svg create mode 100644 docs/source/images/firmware/mr_buffer_et-blocks.svg create mode 100644 docs/source/images/firmware/readout_pfb_v2-blocks.svg create mode 100644 docs/source/images/firmware/readout_pfb_v3-blocks.svg create mode 100644 docs/source/images/firmware/readout_v2-blocks.svg create mode 100644 docs/source/images/firmware/sg_int4_v2-blocks.svg create mode 100644 docs/source/images/firmware/sg_mixmux8-blocks.svg create mode 100644 docs/source/images/firmware/sg_mux8-blocks.svg create mode 100644 docs/source/images/firmware/sg_v4-blocks.svg create mode 100644 docs/source/images/firmware/sg_v6-blocks.svg create mode 100644 docs/source/images/firmware/support_cores-blocks.svg create mode 100644 docs/source/images/firmware/tprocv2-blocks.svg diff --git a/docs/source/firmware.rst b/docs/source/firmware.rst index 6291cce9c..e7a9c37af 100644 --- a/docs/source/firmware.rst +++ b/docs/source/firmware.rst @@ -42,6 +42,15 @@ Sampling frequency of ADC blocks is given by the variable ``soc.fs_adc``. Sampling frequency of DACs is stored in variable ``soc.fs_dac``. Fast-speed buffers were removed to save memory space. Raw data can be captured after x8 down-sampling. +.. figure:: images/firmware/firmware-overview.svg + :align: center + :width: 85% + + System-level block diagram: the tProcessor sequences the signal + generators (SG) and readouts, which sit between it and the DACs/ADCs; + the Zynq PS configures everything over AXI (purple) and is the boundary + between the PS (software) and PL (FPGA fabric) sides of the chip. + Signal Generator v6 (SG-v6) --------------------------- diff --git a/docs/source/images/firmware/dyn_readout-blocks.svg b/docs/source/images/firmware/dyn_readout-blocks.svg new file mode 100644 index 000000000..aa3a0c702 --- /dev/null +++ b/docs/source/images/firmware/dyn_readout-blocks.svg @@ -0,0 +1,493 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/firmware/firmware-overview.svg b/docs/source/images/firmware/firmware-overview.svg new file mode 100644 index 000000000..a37e9f0c5 --- /dev/null +++ b/docs/source/images/firmware/firmware-overview.svg @@ -0,0 +1,471 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/firmware/kidsim-blocks.svg b/docs/source/images/firmware/kidsim-blocks.svg new file mode 100644 index 000000000..101d97269 --- /dev/null +++ b/docs/source/images/firmware/kidsim-blocks.svg @@ -0,0 +1,1002 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/firmware/mr_buffer_et-blocks.svg b/docs/source/images/firmware/mr_buffer_et-blocks.svg new file mode 100644 index 000000000..744354086 --- /dev/null +++ b/docs/source/images/firmware/mr_buffer_et-blocks.svg @@ -0,0 +1,837 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/firmware/readout_pfb_v2-blocks.svg b/docs/source/images/firmware/readout_pfb_v2-blocks.svg new file mode 100644 index 000000000..04fe9de37 --- /dev/null +++ b/docs/source/images/firmware/readout_pfb_v2-blocks.svg @@ -0,0 +1,791 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/firmware/readout_pfb_v3-blocks.svg b/docs/source/images/firmware/readout_pfb_v3-blocks.svg new file mode 100644 index 000000000..5c44fcb5d --- /dev/null +++ b/docs/source/images/firmware/readout_pfb_v3-blocks.svg @@ -0,0 +1,792 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/firmware/readout_v2-blocks.svg b/docs/source/images/firmware/readout_v2-blocks.svg new file mode 100644 index 000000000..d6b1d0d6f --- /dev/null +++ b/docs/source/images/firmware/readout_v2-blocks.svg @@ -0,0 +1,882 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/firmware/sg_int4_v2-blocks.svg b/docs/source/images/firmware/sg_int4_v2-blocks.svg new file mode 100644 index 000000000..a192ad8da --- /dev/null +++ b/docs/source/images/firmware/sg_int4_v2-blocks.svg @@ -0,0 +1,516 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/firmware/sg_mixmux8-blocks.svg b/docs/source/images/firmware/sg_mixmux8-blocks.svg new file mode 100644 index 000000000..88423ba73 --- /dev/null +++ b/docs/source/images/firmware/sg_mixmux8-blocks.svg @@ -0,0 +1,815 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/firmware/sg_mux8-blocks.svg b/docs/source/images/firmware/sg_mux8-blocks.svg new file mode 100644 index 000000000..4f5ed8a2f --- /dev/null +++ b/docs/source/images/firmware/sg_mux8-blocks.svg @@ -0,0 +1,750 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/firmware/sg_v4-blocks.svg b/docs/source/images/firmware/sg_v4-blocks.svg new file mode 100644 index 000000000..c16d4fe16 --- /dev/null +++ b/docs/source/images/firmware/sg_v4-blocks.svg @@ -0,0 +1,810 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/firmware/sg_v6-blocks.svg b/docs/source/images/firmware/sg_v6-blocks.svg new file mode 100644 index 000000000..5ac480a32 --- /dev/null +++ b/docs/source/images/firmware/sg_v6-blocks.svg @@ -0,0 +1,505 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/firmware/support_cores-blocks.svg b/docs/source/images/firmware/support_cores-blocks.svg new file mode 100644 index 000000000..26bbafbff --- /dev/null +++ b/docs/source/images/firmware/support_cores-blocks.svg @@ -0,0 +1,1185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/firmware/tprocv2-blocks.svg b/docs/source/images/firmware/tprocv2-blocks.svg new file mode 100644 index 000000000..7a4992d66 --- /dev/null +++ b/docs/source/images/firmware/tprocv2-blocks.svg @@ -0,0 +1,1363 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/index.rst b/docs/source/index.rst index 6b193c18a..313295e12 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -66,7 +66,7 @@ The documentation is organized as a **progressive learning path** from beginner .. toctree:: :maxdepth: 2 - :caption: 2. Jupyter Notebook Tutorials + :caption: 2. Basic Tutorials (00-05) tutorials/00_Getting_Started tutorials/01_Basic_Sequencing @@ -74,22 +74,35 @@ The documentation is organized as a **progressive learning path** from beginner tutorials/03_Advanced_Timing tutorials/04_Real_Time_Feedback tutorials/05_Dynamic_Parameters_Subroutines + +.. toctree:: + :maxdepth: 2 + :caption: 3. Intermediate Tutorials (06-09) + tutorials/06_Generators_And_Readouts tutorials/07_Advanced_Generators_And_Readouts tutorials/08_Hardware_Buffers tutorials/09_Appendix_Tips_And_Limits + +.. toctree:: + :maxdepth: 2 + :caption: 4. Advanced Tutorials (10-14) + tutorials/10_Multi_Board_Synchronization tutorials/11_Streaming_And_RealTime_Processing tutorials/12_DSP_Blocks_And_Correlators tutorials/13_Custom_Firmware_Integration tutorials/14_XCOM_Network_Synchronization +The **firmware overview** is the map: which boards QICK supports, which +cores live on each one, and how the tProcessor, signal generators, and +readouts fit together on the FPGA -- read this before diving into any +specific core's page or the assembly-level tProcessor reference. + .. toctree:: :maxdepth: 2 - :caption: 3. Hardware & Firmware Reference + :caption: 5. Firmware Overview - tprocv2_trm - tprocv1 firmware The **readout system** turns ADC samples into the I/Q data your program gets @@ -102,7 +115,7 @@ level detail. .. toctree:: :maxdepth: 2 - :caption: 4. Readout System + :caption: 6. Readout System readout readout_v2 @@ -121,7 +134,7 @@ full worked Python examples shared across the family. .. toctree:: :maxdepth: 2 - :caption: 5. Signal Generators + :caption: 7. Signal Generators generators sg_v6 @@ -138,25 +151,46 @@ it's exposed to Python. .. toctree:: :maxdepth: 2 - :caption: 6. Support & Utility Cores + :caption: 8. Support & Utility Cores support_cores .. toctree:: :maxdepth: 2 - :caption: 7. Technical Topics + :caption: 9. Python API Reference + + modules + +.. toctree:: + :maxdepth: 2 + :caption: 10. Technical Topics topics/index +The **tProcessor v2 reference manual** is assembly-level detail -- +instruction encodings, register bit-fields, timing model -- for when you're +writing or debugging tProc assembly directly, not something you need to read +top-to-bottom to use QICK day to day. + .. toctree:: :maxdepth: 2 - :caption: 8. Python API Reference + :caption: 11. tProcessor v2 Reference - modules + tprocv2_trm + +**tProc v1** is the previous-generation tProcessor, superseded by v2 on all +current firmware. Only relevant if you're maintaining pre-v2 code or +firmware. + +.. toctree:: + :maxdepth: 2 + :caption: 12. Legacy: tProc v1 + + tprocv1 .. toctree:: :maxdepth: 2 - :caption: 9. Community + :caption: 13. Community contact papers @@ -169,15 +203,16 @@ Learning Path Recommendations 1. Read the :doc:`quick_start` guide to set up your board 2. Complete the **Basic Tutorials** (00-05) to understand core concepts 3. Work through **Intermediate Tutorials** (06-09) for practical measurements -4. Explore **Advanced Tutorials** (10-13) for specialized applications +4. Read :doc:`firmware` for the big picture, then explore **Advanced + Tutorials** (10-14) for specialized applications **Already familiar with QICK?** Jump directly to: -- :doc:`tprocv2_trm` for tProcessor instruction reference - :doc:`readout` and :doc:`generators` for the readout/generator hardware reference, organized by which core is on your channel -- :doc:`topics/index` for deep dives on specific topics - :doc:`modules` for full API documentation +- :doc:`topics/index` for deep dives on specific topics +- :doc:`tprocv2_trm` for tProcessor instruction reference Academic Papers ================ diff --git a/docs/source/kidsim.md b/docs/source/kidsim.md index facb475a5..ce29e76fb 100644 --- a/docs/source/kidsim.md +++ b/docs/source/kidsim.md @@ -33,6 +33,17 @@ configuration (DDS/IIR/output-select/puncturing registers) is written through a shared register set and latched into the target lane by writing `ADDR_REG` (the lane index) then pulsing `WE_REG`. +```{figure} images/firmware/kidsim-blocks.svg +:align: center +:width: 90% + +One representative `kidsim_top` lane (of `L`), matching `kidsim_top.sv`'s +own documented datapath: `punct` selects one sample per frame, `kidsim` +does the demodulate-by-DDS / IIR-filter / remodulate resonator +simulation, and the output mux falls back to a delay-matched bypass of +the raw input when that lane's sample isn't the punctured one. +``` + ## 2. Synthesis Parameters ```{list-table} diff --git a/docs/source/mr_buffer_et.rst b/docs/source/mr_buffer_et.rst index cd67a8735..ff80163bf 100644 --- a/docs/source/mr_buffer_et.rst +++ b/docs/source/mr_buffer_et.rst @@ -133,6 +133,15 @@ also how the Python driver computes it -- see Section 5). 3. Datapath -------------------------------------------------------------------- +.. figure:: images/firmware/mr_buffer_et-blocks.svg + :align: center + :width: 85% + + Top-level block diagram: ``NM`` independent capture/storage lanes + (``axis_to_bram_trig`` + ``bram_tdp``) on the write-side clock, + drained through a single ``bram_to_axis_nt`` reader on the read-side + clock -- matches ``mr_buffer.sv``'s own header description exactly. + 3.1 Write side -- ``axis_to_bram_trig`` (one instance per channel) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/source/readout_dynamic.rst b/docs/source/readout_dynamic.rst index 353986d52..568677d9c 100644 --- a/docs/source/readout_dynamic.rst +++ b/docs/source/readout_dynamic.rst @@ -55,6 +55,18 @@ Both are single-tone readouts (one DDS-driven downconversion frequency at a time per channel) -- like ``axis_readout_v2`` and unlike the PFB-based readouts, they do not channelize multiple simultaneous tones. +.. figure:: images/firmware/dyn_readout-blocks.svg + :align: center + :width: 80% + + Block diagram of ``readout_top_dynro`` (``axis_dyn_readout_v1`` is a + thin pass-through wrapper around it, so its ports are effectively the + IP's own). The ADC stream is down-converted once and fans out to both + outputs: straight to ``M0_AXIS`` for the pre-decimation view, and + through ``fir_decim8_dynro`` to ``M1_AXIS`` for the decimated stream + that feeds :doc:`/avg_buffer`. ``fifo_sync`` carries the tProc-pushed + config descriptor (freq/phase/mode) into ``down_conversion_dynro``. + -------------------------------------------------------------------- 2. Synthesis Parameters -------------------------------------------------------------------- diff --git a/docs/source/readout_pfb.rst b/docs/source/readout_pfb.rst index a2ead63b2..53524fac1 100644 --- a/docs/source/readout_pfb.rst +++ b/docs/source/readout_pfb.rst @@ -135,6 +135,15 @@ computed once, shared if two outputs pick the same channel -- there is no way to independently re-tune the same PFB channel differently on two outputs simultaneously. +.. figure:: images/firmware/readout_pfb_v2-blocks.svg + :align: center + :width: 85% + + Top-level block diagram: DDS mixing happens once per PFB channel + (``ddsprod_v``, always active for all 8), and ``pfb_mux`` only picks + which already-mixed channel reaches each output -- the "DDS-before-mux" + ordering described above. + 2.2 Register Map ^^^^^^^^^^^^^^^^^ @@ -199,6 +208,16 @@ v3 has **no ``OUTSEL_REG``**/output-mode-selection mux at all (confirmed: driver sets ``HAS_OUTSEL = False`` for ``AxisPFBReadoutV3``) -- each output always carries the demodulated product, nothing else. +.. figure:: images/firmware/readout_pfb_v3-blocks.svg + :align: center + :width: 85% + + Top-level block diagram -- the opposite ordering from v2: + ``pfb_chsel`` picks a raw channel per output first, then ``ddsprod_v`` + applies an independent per-output DDS. v4 (below) is the same diagram + with ``NOUT=8`` instead of 4 -- RTL-identical apart from the doubled + instance arrays. + 3.2 Register Map ^^^^^^^^^^^^^^^^^ diff --git a/docs/source/readout_v2.rst b/docs/source/readout_v2.rst index 0696ae301..49dce4923 100644 --- a/docs/source/readout_v2.rst +++ b/docs/source/readout_v2.rst @@ -32,6 +32,19 @@ The datapath, in order: decimation by 8. 3. Output to ``axis_avg_buffer``'s ``s_axis``. +.. figure:: images/firmware/readout_v2-blocks.svg + :align: center + :width: 85% + + Top-level block diagram of the current fusesoc-ported RTL + (``readout_top_ro_v2.sv`` / ``down_conversion_ro_v2.sv``), verified + directly against that source. **Note:** this reflects ``N_DDS=8`` + (fixed by the shared, reused ``fir_decim8_dynro`` block) and a 3-way + ``OUTSEL`` mux (product/dds/raw ADC) inside ``down_conversion_ro_v2``, + which differs from the ``N_DDS=16`` / no-``OUTSEL`` description above + -- that prose describes the pre-fusesoc-port ``firmware/ip/ + axis_readout_v2/`` RTL and hasn't been reconciled with the port yet. + -------------------------------------------------------------------- 2. Frequency/Output Control (``ctrl.sv``) -------------------------------------------------------------------- diff --git a/docs/source/sg_int4_v2.rst b/docs/source/sg_int4_v2.rst index 631be8085..633bbe46c 100644 --- a/docs/source/sg_int4_v2.rst +++ b/docs/source/sg_int4_v2.rst @@ -55,6 +55,15 @@ via its own DDS + envelope multiplier) -- it is not multiplexed like ``axis_sg_mux4_v1``, which drives several simultaneous tones from one channel. +.. figure:: images/firmware/sg_int4_v2-blocks.svg + :align: center + :width: 80% + + Top-level block diagram. Unlike SG-v6, there's a single real/imag + ``bram_tdp`` pair at the raw (1/4-rate) table rate -- ``fir_0`` does the + x4 interpolation before the DDS mixer, and there's no output mux: this + core always runs the DDS + multiplier path (see the note below). + .. note:: Unlike SG-v6, ``axis_sg_int4_v2`` has **no** ``GEN_DDS``/``ENVELOPE_TYPE`` diff --git a/docs/source/sg_mixmux8.rst b/docs/source/sg_mixmux8.rst index af61f939a..5c879cdc2 100644 --- a/docs/source/sg_mixmux8.rst +++ b/docs/source/sg_mixmux8.rst @@ -93,6 +93,16 @@ up (or down) in frequency, which is what lets ``axis_sg_mixmux8_v1`` (unlike ``axis_sg_mux8_v1``) place its whole multi-tone output away from DC, including outside the DAC's first Nyquist zone. +.. figure:: images/firmware/sg_mixmux8-blocks.svg + :align: center + :width: 85% + + Top-level block diagram -- identical control/FIFO structure to + ``axis_sg_mux8_v1``, but each ``dds_top_mixmux8`` tone slot is a + complex (I/Q) oscillator and the adder tree is duplicated for both + rails. ``M_AXIS`` carries the already-summed I/Q comb to the RFDC's + own mixer on the DAC tile -- there is no mixer inside this IP. + .. note:: This page documents only ``axis_sg_mixmux8_v1``'s own RTL and driver. diff --git a/docs/source/sg_mux8.rst b/docs/source/sg_mux8.rst index ab6a243e5..b2c3aac4c 100644 --- a/docs/source/sg_mux8.rst +++ b/docs/source/sg_mux8.rst @@ -56,6 +56,16 @@ tones rather than 8, and (for V1/V2) drive a DAC-side digital mixer (``AxisSgMux8V1.HAS_MIXER = False`` -- see the Python Interface section). The mux4 RTL is out of scope for this document. +.. figure:: images/firmware/sg_mux8-blocks.svg + :align: center + :width: 85% + + Top-level block diagram. The 8-bit mask and sample count arrive over + ``S_AXIS`` and are queued in ``fifo_sync``; ``ctrl_sgmux8`` pops one + descriptor at a time and gates the 8 ``dds_top_sgmux8`` tone slots + (each internally phase-coherent NCO + DDS + gain) with mask/en. The + summed, requantized output feeds ``M_AXIS``. + .. _sgmux8-synth-params: -------------------------------------------------------------------- diff --git a/docs/source/sg_v4.rst b/docs/source/sg_v4.rst index af2ba274a..37d89920c 100644 --- a/docs/source/sg_v4.rst +++ b/docs/source/sg_v4.rst @@ -51,6 +51,17 @@ Two source files in ``firmware/ip/axis_signal_gen_v4/src/`` -- ``dither.v`` and ``random_gen.v`` -- are **not part of the active datapath**; see :ref:`sgv4-dithering` below. +.. figure:: images/firmware/sg_v4-blocks.svg + :align: center + :width: 85% + + Top-level block diagram. Same envelope-memory/FIFO building blocks as + SG-v6, but the envelope x DDS complex product goes through a single + ``Gain`` stage and then a *static* real/imag select (``OUTSEL_REG``, + set once from Zynq) instead of SG-v6's per-descriptor 3-way mux -- + this core always runs the DDS path and outputs one 16-bit value per + lane. + -------------------------------------------------------------------- 2. Synthesis Parameters -------------------------------------------------------------------- diff --git a/docs/source/sg_v6.rst b/docs/source/sg_v6.rst index c8d911d7f..67328d41e 100644 --- a/docs/source/sg_v6.rst +++ b/docs/source/sg_v6.rst @@ -35,6 +35,17 @@ And two envelope types: * **COMPLEX** (``ENVELOPE_TYPE = "COMPLEX"``): separate memories for real and imaginary parts. * **REAL** (``ENVELOPE_TYPE = "REAL"``): real part only; the imaginary part is forced to zero. +.. figure:: images/firmware/sg_v6-blocks.svg + :align: center + :width: 80% + + Top-level block diagram: ``ctrl_sgv6`` reads the descriptor FIFO and + drives the ``bram_tdp`` read address, the ``N_DDS``-wide DDS array, and + the output mux/gain, while ``axis_to_bram_sg_nt`` independently loads + envelope samples into the same memory. The three-way mux (envelope × + DDS product / raw DDS / raw envelope) matches ``sgv6.sv``'s ``src_la`` + select -- verified directly against the RTL, not just the block names. + -------------------------------------------------------------------- 2. Synthesis Parameters -------------------------------------------------------------------- diff --git a/docs/source/support_cores.rst b/docs/source/support_cores.rst index 8e991dd8b..0a308a7ce 100644 --- a/docs/source/support_cores.rst +++ b/docs/source/support_cores.rst @@ -13,6 +13,13 @@ don't belong to either one. Each is 1-7 RTL files, so rather than a full page per core (as :doc:`/readout_v2`, :doc:`/sg_v6`, etc. get), they share this one page, one section each. +.. figure:: images/firmware/support_cores-blocks.svg + :align: center + :width: 85% + + Block diagram of all three cores -- each is small enough that this is + effectively its full internal structure, not a simplification. + .. _support-constant-iq: ------------------------------------------------------------------------ diff --git a/docs/source/tprocv2_trm.rst b/docs/source/tprocv2_trm.rst index 4f179869a..95a42c950 100644 --- a/docs/source/tprocv2_trm.rst +++ b/docs/source/tprocv2_trm.rst @@ -375,77 +375,22 @@ Complete Instruction Header Reference 3.1. Block Diagram with Data Flow --------------------------------- -The diagram below shows how data moves through the tProcessor. Follow the arrows to understand pipeline stages. - -:: - - +=======================================================================+ - || PS (ARM) || - || +-------------------+ +-------------------+ || - || | Python script | | DMA controller | || - || | (notebook, CLI) |<-->| (AXI master) | || - || +---------+---------+ +---------+---------+ || - || | | || - +=============|========================|================================+ - | | - | (AXI‑Lite) | (AXI‑Stream, DMA) - v v - +=======================================================================+ - || tProcessor || - || || - || +------------------+ +---------------------------------------+ || - || | AXI_REG bank | | Dispatcher (t_clk domain) | || - || | * tproc_ctrl | | | || - || | * tproc_cfg | | +--------+ +--------+ +-----+ | || - || | * core_cfg | | | WFIFO | | DFIFO | | TFIFO| | || - || | * src_dt | | |(168b) | | (32b) | | (1b) | | || - || +------------------+ | +---+----+ +---+----+ +--+--+ | || - || | | | | | | || - || v | v v v | || - || +==================+ | +-------+ +-------+ +-------+ | || - || || CORE (c_clk) || | | 48‑bit| | 48‑bit| | 48‑bit| | || - || || || | |compar | |compar | |compar | | || - || || +-----------+ || | | & | | & | | & | | || - || || | 5‑stage | || | +---+---+ +---+---+ +---+---+ | || - || || | pipeline | || | | | | | || - || || | * Fetch | || | v v v | || - || || | * Decode | || | +-------+ +-------+ +-------+ | || - || || | * Read | || | | WPORT | | DPORT | | TRIG | | || - || || | * Execute | || | | (analog| | (digital| | (1‑bit| | || - || || | * Write | || | | wave) | | data) | | out) | | || - || || +-----------+ || | +---+---+ +---+---+ +---+---+ | || - || || | || | | | | | || - || || v || +======|============|============|======+ || - || || +----+----+ || v v v || - || || | ALU | || [DACs] [PMODs] [Triggers] || - || || | (DSP) | || || - || || +----+----+ || || - || || | || || - || || v || || - || || +----+----+ || || - || || | DIV | || || - || || | (32 cyc)| || || - || || +----+----+ || || - || || | || || - || || v || || - || || +----+----+ || || - || || | LFSR | || || - || || |(PRNG) | || || - || || +---------+ || || - || || || || - || || +-----------+ || || - || || | Memories | || || - || || | * PMEM | || || - || || | * DMEM | || || - || || | * WMEM | || || - || || +-----------+ || || - || +==================+ || - || || - || +------------------+ || - || | IN_PORT (AXI‑S) | <─── from ADC or external source || - || | (feedback data) | || - || +------------------+ || - +=======================================================================+ +The diagram below shows tProcessor v2's top-level composition, verified +directly against ``tprocv2.sv``'s own instantiations: the AXI-Lite register +bank feeds the start/stop/time-base control and the PS memory-DMA path; +``qproc_core`` (the 5-stage pipeline this chapter covers instruction by +instruction, plus its program/data/wave memories) drives the +``qproc_dispatcher``, which is the actual mechanism behind ``WPORT_WR``/ +``TRIG``/``DPORT_WR`` reaching the outside world -- each gets its own +async FIFO plus a time comparator against the running ``t_clk`` time base +(see Section 3.3, *FIFO Depth and Flow Control*, below for the FIFO side +of this). + +.. figure:: images/firmware/tprocv2-blocks.svg + :align: center + :width: 95% + + Top-level block diagram of ``tprocv2.sv``. 3.2. Clock Domain Crossing (CDC) Explained ------------------------------------------- From 1954ff0d798c135cf0e5c28f0c08676f61b21ed2 Mon Sep 17 00:00:00 2001 From: Horacio Arnaldi Date: Tue, 8 Sep 2026 10:33:00 -0500 Subject: [PATCH 12/23] Fix 5 more block diagrams: floating/overlapping connections kidsim, mr_buffer_et, dyn_readout, and readout_pfb v2/v3 all had connections that landed outside their target box or overlapped a label. Synced from qick_internal. --- .../images/firmware/dyn_readout-blocks.svg | 816 ++++++++++++------ docs/source/images/firmware/kidsim-blocks.svg | 14 +- .../images/firmware/mr_buffer_et-blocks.svg | 5 +- .../images/firmware/readout_pfb_v2-blocks.svg | 4 +- .../images/firmware/readout_pfb_v3-blocks.svg | 4 +- 5 files changed, 551 insertions(+), 292 deletions(-) diff --git a/docs/source/images/firmware/dyn_readout-blocks.svg b/docs/source/images/firmware/dyn_readout-blocks.svg index aa3a0c702..d101dbb72 100644 --- a/docs/source/images/firmware/dyn_readout-blocks.svg +++ b/docs/source/images/firmware/dyn_readout-blocks.svg @@ -1,493 +1,751 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + + + + - + - - - + - - - - - + - - - + + - - + - - - - + - + - - - - - - + + + + + - - - - - - + - - - - + - - - - - + - + + - - + - - - + + + + + + + + + + + + - - + - - - - - - - + - - - - - - + + + - + - + - - + - - - - - + - - - - - + - - - - - - - + - - - - + - - - - + - - + - - - - - - - - - - - - - - - + - + - + - - + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - + - - - - - + - + - - - - - - - - - + - - - - - - + - - - - - + + + - - + - - - - - - - - - + - - - - - - - - - - - - - - - + - - - - - - - + - - - - - + - - + - - - - - - - - - + - - - - - - - - - - - - - - - + + - + - - + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/firmware/kidsim-blocks.svg b/docs/source/images/firmware/kidsim-blocks.svg index 101d97269..f57503b50 100644 --- a/docs/source/images/firmware/kidsim-blocks.svg +++ b/docs/source/images/firmware/kidsim-blocks.svg @@ -845,25 +845,25 @@ - + - + - + - + - + - + - + diff --git a/docs/source/images/firmware/mr_buffer_et-blocks.svg b/docs/source/images/firmware/mr_buffer_et-blocks.svg index 744354086..017e9e76e 100644 --- a/docs/source/images/firmware/mr_buffer_et-blocks.svg +++ b/docs/source/images/firmware/mr_buffer_et-blocks.svg @@ -733,8 +733,9 @@ - - + + + diff --git a/docs/source/images/firmware/readout_pfb_v2-blocks.svg b/docs/source/images/firmware/readout_pfb_v2-blocks.svg index 04fe9de37..39c81178a 100644 --- a/docs/source/images/firmware/readout_pfb_v2-blocks.svg +++ b/docs/source/images/firmware/readout_pfb_v2-blocks.svg @@ -681,8 +681,8 @@ - - + + diff --git a/docs/source/images/firmware/readout_pfb_v3-blocks.svg b/docs/source/images/firmware/readout_pfb_v3-blocks.svg index 5c44fcb5d..daf21bfa2 100644 --- a/docs/source/images/firmware/readout_pfb_v3-blocks.svg +++ b/docs/source/images/firmware/readout_pfb_v3-blocks.svg @@ -648,8 +648,8 @@ - - + + From 73d30459191fd72b3ba05b53a604b73bbce7302d Mon Sep 17 00:00:00 2001 From: Horacio Arnaldi Date: Tue, 8 Sep 2026 15:45:20 -0500 Subject: [PATCH 13/23] docs: add QICKBox RF daughtercards tutorial, fix generator-types table New tutorial 15 covers QICKBox RF/Balun daughtercards: attenuators, ADMV8818 tunable filters, and saturation checks, adapted from openquantumhardware/QCE2025's qickbox_rf.ipynb (trimmed to the QICKBox-specific content; generic readout/sweep/pulse-sequence material is already covered by tutorials 01/02/05/06/07). Also fixes the generator-types comparison table in tutorial 07: the Full-Speed/Interpolated rows described pulse shaping instead of the actual tradeoff, which is PL logic usage. --- docs/source/index.rst | 3 +- .../07_Advanced_Generators_And_Readouts.ipynb | 4 +- .../15_QICKBox_RF_Daughtercards.ipynb | 551 ++++++++++++++++++ docs/source/tutorials/README.md | 7 +- 4 files changed, 560 insertions(+), 5 deletions(-) create mode 100644 docs/source/tutorials/15_QICKBox_RF_Daughtercards.ipynb diff --git a/docs/source/index.rst b/docs/source/index.rst index 313295e12..8c1673424 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -86,13 +86,14 @@ The documentation is organized as a **progressive learning path** from beginner .. toctree:: :maxdepth: 2 - :caption: 4. Advanced Tutorials (10-14) + :caption: 4. Advanced Tutorials (10-15) tutorials/10_Multi_Board_Synchronization tutorials/11_Streaming_And_RealTime_Processing tutorials/12_DSP_Blocks_And_Correlators tutorials/13_Custom_Firmware_Integration tutorials/14_XCOM_Network_Synchronization + tutorials/15_QICKBox_RF_Daughtercards The **firmware overview** is the map: which boards QICK supports, which cores live on each one, and how the tProcessor, signal generators, and diff --git a/docs/source/tutorials/07_Advanced_Generators_And_Readouts.ipynb b/docs/source/tutorials/07_Advanced_Generators_And_Readouts.ipynb index 4a6df9e4d..de8474df5 100644 --- a/docs/source/tutorials/07_Advanced_Generators_And_Readouts.ipynb +++ b/docs/source/tutorials/07_Advanced_Generators_And_Readouts.ipynb @@ -203,8 +203,8 @@ "╠════════════════════════╦═════════════════════════════════════════════════════════════════════════════════════╣\n", "║ Generator Type ║ Best For ║\n", "╠════════════════════════╬═════════════════════════════════════════════════════════════════════════════════════╣\n", - "║ Full-Speed (FS) ║ Single tone, maximum bandwidth (10 Gsps), simple pulses ║\n", - "║ Interpolated (INT) ║ Fine frequency resolution, needs mixer_freq for upconversion, shaped pulses ║\n", + "║ Full-Speed (FS) ║ Single tone, maximum bandwidth (10 Gsps), needs more PL logic ║\n", + "║ Interpolated (INT) ║ Fine frequency resolution, needs mixer_freq for upconversion, less PL logic ║\n", "║ Full-Speed Mux (FSMUX) ║ Multi-tone, phase-coherent, up to 8 tones @ 10 Gsps, constant envelope ║\n", "║ Mixer-Mux (MIXMUX) ║ Multi-tone, phase-coherent, lower sample rate (7 Gsps), better SFDR ║\n", "╠════════════════════════╩═════════════════════════════════════════════════════════════════════════════════════╣\n", diff --git a/docs/source/tutorials/15_QICKBox_RF_Daughtercards.ipynb b/docs/source/tutorials/15_QICKBox_RF_Daughtercards.ipynb new file mode 100644 index 000000000..4e66bba0e --- /dev/null +++ b/docs/source/tutorials/15_QICKBox_RF_Daughtercards.ipynb @@ -0,0 +1,551 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 15 - QICKBox RF Daughtercards\n", + "\n", + "**Objective:** Learn how to use the QICKBox's RF and Balun daughtercards: setting the digitally\n", + "controlled attenuators, and shaping the signal chain with the ADMV8818 tunable RF filters. This\n", + "notebook covers:\n", + "- What the QICKBox is and how its daughtercards map to DAC/ADC channels\n", + "- Setting DAC/ADC attenuators on the RF and Balun daughtercards\n", + "- Bypassing, sweeping, and combining the ADMV8818 low-pass/high-pass filter bands\n", + "- Measuring signal power to check for saturation\n", + "\n", + "**Prerequisites:**\n", + "- A QICKBox with an RF-out and RF-in daughtercard (and, optionally, Balun-out/Balun-in daughtercards)\n", + " installed, wired for loopback per the diagram below\n", + "- Completed basic tutorials (00-05) and [`06_Generators_And_Readouts.ipynb`](../tutorials/06_Generators_And_Readouts.ipynb)\n", + " for generator/readout/pulse concepts, which are not re-explained here\n", + "- Firmware bitstream built for the QICKBox variant of your board (`RFQickSoc216V1` or equivalent)\n", + "\n", + "**References:**\n", + "- QICK Documentation: https://docs.qick.dev\n", + "- Firmware overview: [Firmware Overview](../firmware.rst)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Overview\n", + "\n", + "The QICKBox is a QICK carrier board that breaks DAC/ADC channels out to swappable RF daughtercards,\n", + "instead of driving SMAs directly off the RFSoC. Two daughtercard types matter here:\n", + "\n", + "- **RF daughtercards** (RF-out / RF-in): chains of amplifiers and digitally controlled attenuators\n", + " tuned to drive a fridge directly, with no additional warm amplification. They also carry an\n", + " **ADMV8818** digitally tunable filter, used to remove spurious Nyquist images on the DAC side and\n", + " Nyquist-folded noise on the ADC side.\n", + "- **Balun daughtercards** (Balun-out / Balun-in): a simpler passive path (no attenuators, no filter),\n", + " useful as a reference/loopback channel or for signals that don't need the RF chain's gain and filtering.\n", + "\n", + "Each daughtercard slot exposes several physical DAC/ADC ports; which *firmware* generator/readout\n", + "channel a given port maps to depends on the bitstream build.\n", + "\n", + "### Wiring for this notebook\n", + "\n", + "```\n", + "\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n", + "\u2502 QICKBox Loopback Wiring \u2502\n", + "\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n", + "\u2502 DAC slot 1: RF-out daughtercard (ports 4-7) \u2502\n", + "\u2502 DAC slot 2: Balun-out daughtercard (ports 8-12) \u2502\n", + "\u2502 ADC slot 2: RF-in daughtercard (ports 4-5) \u2502\n", + "\u2502 ADC slot 3: Balun-in daughtercard (ports 6-7) \u2502\n", + "\u2502 \u2502\n", + "\u2502 DAC port 4 \u2500\u2500[40 dB attenuator]\u2500\u2500\u25ba ADC port 5 \u2502\n", + "\u2502 DAC port 5 \u2500\u2500[40 dB attenuator]\u2500\u2500\u25ba ADC port 4 \u2502\n", + "\u2502 DAC port 8 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25ba ADC port 6 \u2502\n", + "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n", + "```\n", + "\n", + "**Important notes:**\n", + "- Adjust the port numbers and firmware channel numbers below to match your own daughtercard slots\n", + " and cabling -- the mapping is fixed by the bitstream, not by this notebook.\n", + "- The RF daughtercards' amplifiers can saturate (or clip the ADC) if you drive them with too little\n", + " attenuation. Start with generous attenuation (as in [Section 3](#3.-Daughtercard-Attenuators)) and\n", + " reduce it gradually while watching the readout amplitude.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Setup and Initialization" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Standard imports\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "from tqdm.auto import tqdm\n", + "\n", + "from qick.asm_v2 import AveragerProgramV2, QickSweep1D\n", + "from qick.rfboard import RFQickSoc216V1\n", + "\n", + "# Connect to the board (adjust the path to your firmware)\n", + "BITSTREAM_PATH = 'qick_216_rfbv2.bit' # <--- CHANGE THIS\n", + "soc = RFQickSoc216V1(BITSTREAM_PATH)\n", + "soccfg = soc\n", + "\n", + "# Firmware channel numbers for the generators/readouts wired above\n", + "GEN_CH_RF = 5\n", + "GEN_CH_BALUN = 8\n", + "RO_CH_RF = 0\n", + "RO_CH_BALUN = 1\n", + "\n", + "# Physical DAC/ADC ports on the RF daughtercards (attenuators/filters are\n", + "# addressed by port, not by firmware channel)\n", + "DAC_RF = 5\n", + "ADC_RF = 4\n", + "\n", + "# Starting attenuations, dB (0 through 31.75) -- generous, to avoid\n", + "# saturating the chain before we've characterized it\n", + "DAC_ATT = [0, 10]\n", + "ADC_ATT = 25\n", + "\n", + "print(f\"Firmware: {soc.get_cfg()['fw_version']}\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Daughtercard Attenuators\n", + "\n", + "`rfb_set_dac_rf`/`rfb_set_adc_rf` set the digitally controlled attenuators on an RF daughtercard's\n", + "DAC/ADC port. The DAC side takes two attenuator values (two stages in the chain); the ADC side takes\n", + "one. Let's set some starting attenuations and run a loopback pulse through the RF daughtercard to\n", + "confirm the signal chain is working, using decimated readout so we can look at the pulse shape.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"set DAC attenuators:\", soc.rfb_set_dac_rf(DAC_RF, *DAC_ATT))\n", + "print(\"set ADC attenuators:\", soc.rfb_set_adc_rf(ADC_RF, ADC_ATT))\n", + "\n", + "\n", + "class LoopbackProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " self.declare_gen(ch=gen_ch, nqz=cfg['nqz'], mixer_freq=cfg['mixer_freq'], ro_ch=ro_ch)\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'])\n", + " self.add_readoutconfig(ch=ro_ch, name=\"myro\", freq=cfg['freq'], gen_ch=gen_ch, outsel='product')\n", + " self.add_cosine(ch=gen_ch, name=\"ramp\", length=cfg['ramp_len'], even_length=True)\n", + " self.add_pulse(ch=gen_ch, name=\"mypulse\", ro_ch=ro_ch,\n", + " style=\"flat_top\",\n", + " envelope=\"ramp\",\n", + " freq=cfg['freq'],\n", + " length=cfg['flat_len'],\n", + " phase=cfg['phase'],\n", + " gain=cfg['gain'])\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"myro\", t=0)\n", + "\n", + " def _body(self, cfg):\n", + " self.delay_auto()\n", + " self.pulse(ch=cfg['gen_ch'], name=\"mypulse\", t=0.0)\n", + " self.trigger(ros=[cfg['ro_ch']], t=cfg['trig_time'])\n", + "\n", + "\n", + "config = {'gen_ch': GEN_CH_RF,\n", + " 'ro_ch': RO_CH_RF,\n", + " 'mixer_freq': 6000,\n", + " 'freq': 6000,\n", + " 'nqz': 2,\n", + " 'trig_time': 0.0,\n", + " 'ro_len': 3.0,\n", + " 'flat_len': 1.0,\n", + " 'ramp_len': 1.0,\n", + " 'phase': 0,\n", + " 'gain': 1.0}\n", + "\n", + "# start the RF filters centered on the pulse frequency (Section 4 covers this call in detail)\n", + "soc.rfb_set_dac_filter(DAC_RF, fc=config['freq'] / 1000, ftype='bandpass', bw=1.0)\n", + "soc.rfb_set_adc_filter(ADC_RF, fc=config['freq'] / 1000, ftype='bandpass', bw=1.0)\n", + "\n", + "prog = LoopbackProgram(soccfg, reps=1, final_delay=0.5, cfg=config)\n", + "iq_list = prog.acquire_decimated(soc, rounds=10)\n", + "\n", + "t = prog.get_time_axis(ro_index=0)\n", + "iq = iq_list[0]\n", + "plt.plot(t, iq[:, 0], label=\"I value\")\n", + "plt.plot(t, iq[:, 1], label=\"Q value\")\n", + "plt.plot(t, np.abs(iq.dot((1, 1j))), label=\"magnitude\")\n", + "plt.legend()\n", + "plt.ylabel(\"amplitude [ADU]\")\n", + "plt.xlabel(\"time [us]\");\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Observation:** with the attenuators and filter both centered on the pulse frequency, you should see\n", + "a clean flat-top pulse. If the magnitude trace is clipped/flat-topped, add more attenuation; if it's\n", + "very small and noisy, reduce it.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Daughtercard RF Filters (ADMV8818)\n", + "\n", + "Each RF daughtercard's ADMV8818 filter has four selectable low-pass **bands** and four high-pass\n", + "**bands**, each tunable through 16 **states** -- 3-bit band select + 4-bit state select per filter\n", + "type. `rfb_set_dac_filter`/`rfb_set_adc_filter` wrap this into a `fc`/`bw`/`ftype` (\"bandpass\" or\n", + "\"bypass\") interface. To characterize the filter itself, it's more direct to drive the underlying\n", + "registers, which is what `set_filter` below does.\n", + "\n", + "We measure the filter response as an S21 sweep: play a swept-frequency tone and read back the\n", + "demodulated amplitude at each frequency.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class FreqSweepProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " self.declare_gen(ch=gen_ch, nqz=cfg['nqz'], mixer_freq=cfg['mixer_freq'], ro_ch=ro_ch)\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'])\n", + " self.add_loop(\"myloop\", self.cfg[\"steps\"])\n", + " self.add_readoutconfig(ch=ro_ch, name=\"myro\", freq=cfg['freq'], gen_ch=gen_ch)\n", + " self.add_pulse(ch=gen_ch, name=\"mypulse\", ro_ch=ro_ch,\n", + " style=\"const\",\n", + " freq=cfg['freq'],\n", + " length=cfg['pulse_len'],\n", + " phase=cfg['phase'],\n", + " gain=cfg['gain'])\n", + "\n", + " def _body(self, cfg):\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"myro\", t=0)\n", + " self.pulse(ch=cfg['gen_ch'], name=\"mypulse\", t=0)\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'])\n", + "\n", + "\n", + "def measure_s21(gen_ch, ro_ch, nqz, gain, steps=101, dds_range=0.45, overlap=0, plot=False, progress=True):\n", + " # the interpolated-generator frequency range is limited, so stitch several\n", + " # mixer_freq-centered sweeps together to cover a wide band\n", + " soc.clear_interrupts()\n", + " config = {'steps': steps, 'gen_ch': gen_ch, 'ro_ch': ro_ch, 'nqz': nqz,\n", + " 'trig_time': 0.4, 'pulse_len': 10.0, 'ro_len': 10.1, 'phase': 0, 'gain': gain}\n", + " allfreqs, allpowers = [], []\n", + " f_dds = soccfg['gens'][gen_ch]['f_dds']\n", + " mixer_freqs = np.arange(0.5, 10000 / f_dds, dds_range * 2 - overlap) * f_dds\n", + " for mixer_freq in tqdm(mixer_freqs, disable=not progress):\n", + " config['mixer_freq'] = mixer_freq\n", + " config['freq'] = QickSweep1D(\"myloop\", mixer_freq - dds_range * f_dds, mixer_freq + dds_range * f_dds)\n", + " prog = FreqSweepProgram(soccfg, reps=10, final_delay=1.0, cfg=config)\n", + " freqs = prog.get_pulse_param('myro', 'freq', as_array=True)\n", + " iq_list = prog.acquire(soc, rounds=1, progress=False)\n", + " powers = 20 * np.log10(np.abs(iq_list[0][0].dot([1, 1j])))\n", + " allfreqs.append(freqs)\n", + " allpowers.append(powers)\n", + " if plot:\n", + " plt.plot(freqs, powers, label=\"mixer_freq=%f\" % (mixer_freq))\n", + " return np.array(allfreqs).flatten(), np.array(allpowers).flatten()\n", + "\n", + "\n", + "def set_filter(lpf, hpf, filt=0):\n", + " \"\"\"Drive the ADMV8818 band-select (lpf/hpf) and state (filt) registers directly,\n", + " on both the RF-in and RF-out daughtercards.\"\"\"\n", + " sw = 0xc0 + (hpf << 3) + lpf\n", + " filt_bits = (filt << 4) + filt\n", + " rfb_ch = soc.adc_chains[ADC_RF]\n", + " with soc.board_sel.enable_context(rfb_ch.card_num):\n", + " rfb_ch.filter.write_reg('WR0_SW', sw)\n", + " rfb_ch.filter.write_reg('WR0_FILTER', filt_bits)\n", + " rfb_ch = soc.dac_chains[DAC_RF]\n", + " with soc.board_sel.enable_context(rfb_ch.card_num):\n", + " rfb_ch.filter.write_reg('WR0_SW', sw)\n", + " rfb_ch.filter.write_reg('WR0_FILTER', filt_bits)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Bypass mode\n", + "\n", + "With the filters in bypass mode there's no rejection of Nyquist images/aliases, so we need to crank up\n", + "all of the attenuators to avoid saturating the chain.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"set DAC attenuators:\", soc.rfb_set_dac_rf(DAC_RF, 30, 30))\n", + "print(\"set ADC attenuators:\", soc.rfb_set_adc_rf(ADC_RF, 30))\n", + "soc.rfb_set_rfadc_attenuator(ADC_RF, 10)\n", + "soc.rfb_set_dac_filter(DAC_RF, fc=0, ftype='bypass')\n", + "soc.rfb_set_adc_filter(ADC_RF, fc=0, ftype='bypass')\n", + "\n", + "plt.plot(*measure_s21(GEN_CH_RF, RO_CH_RF, nqz=2, gain=1.0, steps=501, dds_range=0.45, overlap=0.1))\n", + "plt.ylabel(\"S21 [arb. dB]\")\n", + "plt.xlabel(\"Frequency [MHz]\")\n", + "plt.ylim(bottom=0)\n", + "plt.title(\"bypass mode\");\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Sweeping bands and states\n", + "\n", + "Let's work our way through the low-pass and high-pass filter banks: first the four bands (at a fixed\n", + "state), then all 16 states within one band.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for lpf in tqdm(range(0, 5)):\n", + " set_filter(lpf, 0, 0)\n", + " plt.plot(*measure_s21(GEN_CH_RF, RO_CH_RF, 2, 1.0, progress=False), label=\"lpf=%d\" % (lpf))\n", + "plt.ylabel(\"S21 [arb. dB]\")\n", + "plt.xlabel(\"Frequency [MHz]\")\n", + "plt.ylim(bottom=0)\n", + "plt.title(\"LPF bands, state=0\")\n", + "plt.legend();\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for state in tqdm(range(0, 16)):\n", + " set_filter(2, 0, state)\n", + " plt.plot(*measure_s21(GEN_CH_RF, RO_CH_RF, 2, 1.0, progress=False), label=\"state=%d\" % (state))\n", + "plt.ylabel(\"S21 [arb. dB]\")\n", + "plt.xlabel(\"Frequency [MHz]\")\n", + "plt.ylim(bottom=0)\n", + "plt.title(\"LPF states, band=2\")\n", + "plt.legend();\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for hpf in tqdm(range(0, 5)):\n", + " set_filter(0, hpf, 0)\n", + " plt.plot(*measure_s21(GEN_CH_RF, RO_CH_RF, 2, 1.0, progress=False), label=\"hpf=%d\" % (hpf))\n", + "plt.ylabel(\"S21 [arb. dB]\")\n", + "plt.xlabel(\"Frequency [MHz]\")\n", + "plt.ylim(bottom=0)\n", + "plt.title(\"HPF bands, state=0\")\n", + "plt.legend();\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for state in tqdm(range(0, 16)):\n", + " set_filter(0, 2, state)\n", + " plt.plot(*measure_s21(GEN_CH_RF, RO_CH_RF, 2, 1.0, progress=False), label=\"state=%d\" % (state))\n", + "plt.ylabel(\"S21 [arb. dB]\")\n", + "plt.xlabel(\"Frequency [MHz]\")\n", + "plt.ylim(bottom=0)\n", + "plt.title(\"HPF states, band=2\")\n", + "plt.legend();\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Combining LPF + HPF into a bandpass\n", + "\n", + "This is what `rfb_set_dac_filter`/`rfb_set_adc_filter` with `ftype='bandpass'` do for you: they pick a\n", + "matching LPF/HPF band+state pair to approximate the requested center frequency `fc` and bandwidth `bw`.\n", + "As the passband narrows, more attenuation can be removed for the same signal level -- the filter itself\n", + "is doing some of the rejection work that attenuation was doing in bypass mode.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for fc, bw, dac_att2, adc_att in [(5, 1.0, 30, 30), (5.5, 0.5, 20, 25), (6, 0.5, 20, 25), (7, 1.0, 15, 20)]:\n", + " soc.rfb_set_dac_filter(DAC_RF, fc=fc, ftype='bandpass', bw=bw)\n", + " soc.rfb_set_adc_filter(ADC_RF, fc=fc, ftype='bandpass', bw=bw)\n", + " soc.rfb_set_dac_rf(DAC_RF, 0, dac_att2)\n", + " soc.rfb_set_adc_rf(ADC_RF, adc_att)\n", + " plt.plot(*measure_s21(GEN_CH_RF, RO_CH_RF, nqz=2, gain=1.0, steps=501, dds_range=0.45, overlap=0.1),\n", + " label=\"fc=%.1f, bw=%.1f\" % (fc, bw))\n", + "\n", + "# leave the chain in a safe, heavily attenuated state\n", + "soc.rfb_set_dac_rf(DAC_RF, 30, 30)\n", + "soc.rfb_set_adc_rf(ADC_RF, 30)\n", + "\n", + "plt.ylabel(\"S21 [arb. dB]\")\n", + "plt.xlabel(\"Frequency [MHz]\")\n", + "plt.ylim(bottom=0)\n", + "plt.xlim((3000, 9000))\n", + "plt.legend();\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Measuring Power and Checking for Saturation\n", + "\n", + "When you change gain, attenuation, or filtering, it's useful to have a quick way to measure the\n", + "resulting readout amplitude -- both to compare configurations and to check you haven't saturated the\n", + "DAC output stage or the ADC input. `PeriodicProgram` plays a continuous tone so the readout amplitude\n", + "converges to a steady-state value; `measure_gain` wraps it into a one-line power measurement for a\n", + "given generator gain and pair of attenuator settings.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class PeriodicProgram(AveragerProgramV2):\n", + " def _initialize(self, cfg):\n", + " ro_ch = cfg['ro_ch']\n", + " gen_ch = cfg['gen_ch']\n", + " self.declare_gen(ch=gen_ch, nqz=cfg['nqz'], mixer_freq=cfg['mixer_freq'], ro_ch=ro_ch)\n", + " self.declare_readout(ch=ro_ch, length=cfg['ro_len'])\n", + " self.add_readoutconfig(ch=ro_ch, name=\"myro\", freq=cfg['freq'], gen_ch=gen_ch, outsel='product')\n", + " self.add_pulse(ch=gen_ch, name=\"mypulse\", ro_ch=ro_ch,\n", + " style=\"const\",\n", + " freq=cfg['freq'],\n", + " length=cfg['flat_len'],\n", + " phase=cfg['phase'],\n", + " gain=cfg['gain'],\n", + " mode='periodic')\n", + " self.send_readoutconfig(ch=cfg['ro_ch'], name=\"myro\", t=0)\n", + " self.pulse(ch=cfg['gen_ch'], name=\"mypulse\", t=0)\n", + "\n", + " def _body(self, cfg):\n", + " self.trigger(ros=[cfg['ro_ch']], pins=[0], t=cfg['trig_time'], mr=True)\n", + "\n", + "\n", + "def measure_gain(gain, dac_att1, dac_att2, adc_att):\n", + " config = {'gen_ch': GEN_CH_RF, 'ro_ch': RO_CH_RF, 'mixer_freq': 6000, 'freq': 6000, 'nqz': 2,\n", + " 'trig_time': 0.0, 'ro_len': 10.0, 'flat_len': 1.0, 'phase': 0, 'gain': gain}\n", + " soc.rfb_set_dac_rf(DAC_RF, dac_att1, dac_att2)\n", + " soc.rfb_set_adc_rf(ADC_RF, adc_att)\n", + " prog = PeriodicProgram(soccfg, reps=1000, final_delay=0.5, cfg=config)\n", + " mag = np.abs(prog.acquire(soc, progress=False)[0][0].dot([1, 1j]))\n", + " soc.reset_gens()\n", + " soc.clear_interrupts()\n", + " return mag\n", + "\n", + "\n", + "# baseline, then compare a few knobs against it, each as a dB change\n", + "ref_mag = measure_gain(0.5, DAC_ATT[0], DAC_ATT[1], ADC_ATT)\n", + "print(\"reference amplitude: %f\" % (ref_mag))\n", + "\n", + "mag = measure_gain(0.5, DAC_ATT[0], DAC_ATT[1] - 3, ADC_ATT)\n", + "print(\"with -3 dB DAC att2: amplitude %f, a %.2f dB change\" % (mag, 20 * np.log10(mag / ref_mag)))\n", + "\n", + "mag = measure_gain(0.5, DAC_ATT[0], DAC_ATT[1], ADC_ATT - 3)\n", + "print(\"with -3 dB ADC att: amplitude %f, a %.2f dB change\" % (mag, 20 * np.log10(mag / ref_mag)))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Watch for saturation:** if the measured amplitude stops scaling linearly as you reduce attenuation\n", + "(dB change stops matching the attenuator step), you've saturated the DAC output amp, the ADC front end,\n", + "or both -- back off and re-measure.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. Summary\n", + "\n", + "You have learned:\n", + "\n", + "1. **QICKBox daughtercards**: RF daughtercards (amplifiers + attenuators + ADMV8818 filter) vs.\n", + " Balun daughtercards (simple passive path), and how physical ports differ from firmware channels\n", + "2. **Attenuators**: `rfb_set_dac_rf`/`rfb_set_adc_rf` to set per-stage attenuation on a daughtercard port\n", + "3. **ADMV8818 filters**: bypass mode, sweeping LPF/HPF bands and states, and combining them into a\n", + " bandpass response via `rfb_set_dac_filter`/`rfb_set_adc_filter`\n", + "4. **Saturation checking**: using a periodic tone and `measure_gain` to confirm gain/attenuation changes\n", + " are still in the linear regime\n", + "\n", + "### Key Takeaways\n", + "\n", + "- Filtering and attenuation trade off: a narrower bandpass filter rejects more out-of-band noise/images,\n", + " letting you run with less attenuation for the same in-band signal level\n", + "- Always start a new configuration with generous attenuation and reduce it while watching the readout\n", + " amplitude, rather than guessing a low value up front\n", + "- Balun daughtercards are the simplest way to get a reference/loopback channel without the RF chain's\n", + " gain and filtering in the way\n", + "\n", + "### Next Steps\n", + "\n", + "- Return to [`07_Advanced_Generators_And_Readouts.ipynb`](./07_Advanced_Generators_And_Readouts.ipynb)\n", + " for multiplexed generators/readouts and the PFB readout channelizer, which apply equally to signals\n", + " routed through these daughtercards\n", + "- See the [Firmware Overview](../firmware.rst) for how daughtercard ports map to generator/readout\n", + " channels in a given bitstream\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/source/tutorials/README.md b/docs/source/tutorials/README.md index 526204ce8..8cdc807f7 100644 --- a/docs/source/tutorials/README.md +++ b/docs/source/tutorials/README.md @@ -30,7 +30,7 @@ This directory contains Jupyter notebooks that introduce the QICK framework and | 08 | `08_Hardware_Buffers.ipynb` | DDR4 and MR buffers, data capture | | 09 | `09_Appendix_Tips_And_Limits.ipynb` | Common errors, limits, debugging tips | -### Advanced (10–14) +### Advanced (10–15) | # | Notebook | Description | |:-|:---|:---| @@ -39,6 +39,7 @@ This directory contains Jupyter notebooks that introduce the QICK framework and | 12 | `12_DSP_Blocks_And_Correlators.ipynb` | FIR filters, DDS tuning, hardware correlators | | 13 | `13_Custom_Firmware_Integration.ipynb` | Adding custom Verilog/VHDL, AXI-lite interface, rebuilding | | 14 | `14_XCOM_Network_Synchronization.ipynb` | Full mesh network for multi-board synchronization and low-latency communication (requires FMC transceiver board) | +| 15 | `15_QICKBox_RF_Daughtercards.ipynb` | QICKBox RF/Balun daughtercards: attenuators, ADMV8818 tunable filters, saturation checks (requires QICKBox with RF daughtercards) | ## Usage @@ -93,12 +94,14 @@ print(f"tProc cores: {soc.num_tprocs}") * Notebooks 00–09 are self-contained and work on any QICK setup -* Notebooks 10–14 require additional hardware resources (multi-board, streaming, DSP48) +* Notebooks 10–15 require additional hardware resources (multi-board, streaming, DSP48, QICKBox) * Notebook 13 requires a licensed Vivado installation for custom firmware compilation * Notebook 14 (XCOM) requires additional hardware: FMC transceiver board and external hub +* Notebook 15 requires a QICKBox with RF (and optionally Balun) daughtercards installed + ## Troubleshooting If you see "Bitstream not found", check `BITSTREAM_PATH` From cd9ed3bd9b6f963eb0ec94e0f1055867e541b50f Mon Sep 17 00:00:00 2001 From: Horacio Arnaldi Date: Tue, 8 Sep 2026 16:00:07 -0500 Subject: [PATCH 14/23] docs: fix mismatched backtick in time_taggers docstring references Five QickSoc.tt_* docstrings wrote `time_taggers' (backtick open, apostrophe close) instead of matching backticks, which docutils couldn't parse as an inline reference. Synced from qick_internal. --- qick_lib/qick/qick.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/qick_lib/qick/qick.py b/qick_lib/qick/qick.py index c8117d3f6..15df38c4b 100644 --- a/qick_lib/qick/qick.py +++ b/qick_lib/qick/qick.py @@ -1954,7 +1954,7 @@ def tt_arm(self, blk): Parameters ---------- blk : int - The time tagger block to arm (index in `time_taggers' list). + The time tagger block to arm (index in `time_taggers` list). """ self.time_taggers[blk].disarm() self.time_taggers[blk].arm() @@ -1965,7 +1965,7 @@ def tt_disarm(self, blk): Parameters ---------- blk : int - The time tagger block to arm (index in `time_taggers' list). + The time tagger block to arm (index in `time_taggers` list). """ self.time_taggers[blk].disarm() @@ -1976,7 +1976,7 @@ def tt_readmem(self, blk, mem): Parameters ---------- blk : int - The time tagger block to read (index in `time_taggers' list). + The time tagger block to read (index in `time_taggers` list). mem : str "ARM", "SMP", "TAG0"/"TAG1"/"TAG2"/"TAG3" """ @@ -1988,7 +1988,7 @@ def tt_reset(self, blk): Parameters ---------- blk : int - The time tagger block to reset (index in `time_taggers' list). + The time tagger block to reset (index in `time_taggers` list). """ #self.time_taggers[blk].reset() self.time_taggers[blk].flush_mems() @@ -1999,7 +1999,7 @@ def tt_config(self, blk, threshold, wr_smp=32, filt=False, slope=False, invert=F Parameters ---------- blk : int - The time tagger block to flush (index in `time_taggers' list). + The time tagger block to flush (index in `time_taggers` list). threshold : int Tag threshold (-2^15 through 2^15-1). wr_smp : int From e8e7b119a95b5f1aa84068c3a256e47854b30825 Mon Sep 17 00:00:00 2001 From: Horacio Arnaldi Date: Tue, 8 Sep 2026 16:03:18 -0500 Subject: [PATCH 15/23] docs: fix module docstring RST parse error in tprocv2_assembler.py The "Release (March 2024)" banner had an overline but no matching underline, so docutils tried to parse it as a section title and failed. Added the missing underline (matching the FERMI RESEARCH LAB banner above it). Synced from qick_internal. --- qick_lib/qick/tprocv2_assembler.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qick_lib/qick/tprocv2_assembler.py b/qick_lib/qick/tprocv2_assembler.py index 1bc30cd85..5bc2a6edf 100644 --- a/qick_lib/qick/tprocv2_assembler.py +++ b/qick_lib/qick/tprocv2_assembler.py @@ -24,6 +24,7 @@ /////////////////////////////////////////////////////////////////////////////// Release (March 2024) +/////////////////////////////////////////////////////////////////////////////// To be used with qick_processor version 17th or Higher.... """ From afd3a15d24e089152601a5af9a80f83a1253b39d Mon Sep 17 00:00:00 2001 From: Sho Uemura Date: Tue, 8 Sep 2026 18:03:05 -0500 Subject: [PATCH 16/23] move tutorials list off of main TOC --- docs/source/firmware.rst | 2 +- docs/source/index.rst | 29 +------------- docs/source/topics/example_code.rst | 2 +- docs/source/topics/index.rst | 3 +- docs/source/topics/playing_pulses.rst | 2 +- docs/source/tprocv2_trm.rst | 6 +-- .../tutorials.rst => tutorials/index.rst} | 39 ++++++++++--------- 7 files changed, 29 insertions(+), 54 deletions(-) rename docs/source/{topics/tutorials.rst => tutorials/index.rst} (81%) diff --git a/docs/source/firmware.rst b/docs/source/firmware.rst index e7a9c37af..a326415a9 100644 --- a/docs/source/firmware.rst +++ b/docs/source/firmware.rst @@ -520,5 +520,5 @@ Related Documentation * :doc:`/avg_buffer` - Averaged/raw buffer IP downstream of every readout variant * :doc:`/mr_buffer_et` - Multi-rate buffer (DDR4/streaming) shared readout path * :doc:`topics/asmv2_cheatsheet` - tProc v2 assembly quick reference -* :doc:`topics/tutorials` - tProc v2 tutorial examples +* :doc:`tutorials/index` - tProc v2 tutorial examples * `Signal Generator v6 source `_ diff --git a/docs/source/index.rst b/docs/source/index.rst index 8c1673424..ce3e1dde1 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -66,34 +66,9 @@ The documentation is organized as a **progressive learning path** from beginner .. toctree:: :maxdepth: 2 - :caption: 2. Basic Tutorials (00-05) + :caption: 2. Tutorials - tutorials/00_Getting_Started - tutorials/01_Basic_Sequencing - tutorials/02_Parameter_Sweeps - tutorials/03_Advanced_Timing - tutorials/04_Real_Time_Feedback - tutorials/05_Dynamic_Parameters_Subroutines - -.. toctree:: - :maxdepth: 2 - :caption: 3. Intermediate Tutorials (06-09) - - tutorials/06_Generators_And_Readouts - tutorials/07_Advanced_Generators_And_Readouts - tutorials/08_Hardware_Buffers - tutorials/09_Appendix_Tips_And_Limits - -.. toctree:: - :maxdepth: 2 - :caption: 4. Advanced Tutorials (10-15) - - tutorials/10_Multi_Board_Synchronization - tutorials/11_Streaming_And_RealTime_Processing - tutorials/12_DSP_Blocks_And_Correlators - tutorials/13_Custom_Firmware_Integration - tutorials/14_XCOM_Network_Synchronization - tutorials/15_QICKBox_RF_Daughtercards + tutorials/index The **firmware overview** is the map: which boards QICK supports, which cores live on each one, and how the tProcessor, signal generators, and diff --git a/docs/source/topics/example_code.rst b/docs/source/topics/example_code.rst index 184636cca..76702847f 100644 --- a/docs/source/topics/example_code.rst +++ b/docs/source/topics/example_code.rst @@ -5,7 +5,7 @@ Example code from the community List originally contributed by `Jay Chien `_ (`PR #412 `_). -Beyond the tutorials in :doc:`tutorials`, QICK collaborators have shared +Beyond the tutorials in :doc:`../tutorials/index`, QICK collaborators have shared larger example codebases built on top of QICK. These are useful as reference for structuring real measurement code, but are maintained independently of this repository and are not guaranteed to track the latest QICK release. diff --git a/docs/source/topics/index.rst b/docs/source/topics/index.rst index 2c8cee429..b78425637 100644 --- a/docs/source/topics/index.rst +++ b/docs/source/topics/index.rst @@ -26,7 +26,6 @@ These topics assume you have completed the basic tutorials (00-05) and are famil :caption: Quick Reference asmv2_cheatsheet - tutorials tprocv2_migration example_code @@ -100,4 +99,4 @@ When to Use Each Topic - **Coming from tProc v1?** Start with :doc:`tprocv2_migration` - **Looking for full example experiments?** See :doc:`example_code` - **Synchronizing multiple boards?** Read :doc:`xcom` for the network-based solution -- **Need XCOM command details?** See :doc:`XCOM-commands` for the complete command reference \ No newline at end of file +- **Need XCOM command details?** See :doc:`XCOM-commands` for the complete command reference diff --git a/docs/source/topics/playing_pulses.rst b/docs/source/topics/playing_pulses.rst index d39d4e5a0..ae93de753 100644 --- a/docs/source/topics/playing_pulses.rst +++ b/docs/source/topics/playing_pulses.rst @@ -145,4 +145,4 @@ Related Documentation * :doc:`/sg_v6` - Signal Generator v6 documentation, with more worked examples * :doc:`/readout` - Declaring and triggering a readout alongside a pulse * :doc:`/firmware` - Channel assignments and firmware overview -* :doc:`tutorials` - tProc v2 tutorial examples +* :doc:`../tutorials/index` - tProc v2 tutorial examples diff --git a/docs/source/tprocv2_trm.rst b/docs/source/tprocv2_trm.rst index 95a42c950..e2f5b859a 100644 --- a/docs/source/tprocv2_trm.rst +++ b/docs/source/tprocv2_trm.rst @@ -5575,9 +5575,9 @@ tProc/firmware timing, unaffected by PS-side overhead: 13.10. Repository of Examples ----------------------------- -This documentation's own tutorial notebooks (:doc:`topics/tutorials`) are +This documentation's own tutorial notebooks (:doc:`tutorials/index`) are the primary worked-example resource, all runnable on real hardware (or, for -tutorials 00-07, on the :doc:`topics/tutorials`'s Colab-runnable emulator +tutorials 00-07, on the :doc:`tutorials/index`'s Colab-runnable emulator port): .. list-table:: Tutorial Notebooks Covering This Chapter's Topics @@ -5601,7 +5601,7 @@ port): For more elaborate examples (multi-qubit experiments, advanced feedback loops, calibration routines), refer to: -- **Tutorial series** (:doc:`topics/tutorials`) – The full 00-14 series, +- **Tutorial series** (:doc:`tutorials/index`) – The full 00-14 series, from basic sequencing through streaming/DSP, custom firmware integration, and XCOM multi-board network synchronization. - **Official QICK Demos Repository** – diff --git a/docs/source/topics/tutorials.rst b/docs/source/tutorials/index.rst similarity index 81% rename from docs/source/topics/tutorials.rst rename to docs/source/tutorials/index.rst index 2a6fccee0..b158e07db 100644 --- a/docs/source/topics/tutorials.rst +++ b/docs/source/tutorials/index.rst @@ -19,32 +19,33 @@ Tutorials :maxdepth: 1 :caption: Basic Tutorials (00-05) - ../tutorials/00_Getting_Started - ../tutorials/01_Basic_Sequencing - ../tutorials/02_Parameter_Sweeps - ../tutorials/03_Advanced_Timing - ../tutorials/04_Real_Time_Feedback - ../tutorials/05_Dynamic_Parameters_Subroutines + 00_Getting_Started + 01_Basic_Sequencing + 02_Parameter_Sweeps + 03_Advanced_Timing + 04_Real_Time_Feedback + 05_Dynamic_Parameters_Subroutines .. toctree:: :maxdepth: 1 :caption: Intermediate Tutorials (06-09) - ../tutorials/06_Generators_And_Readouts - ../tutorials/07_Advanced_Generators_And_Readouts - ../tutorials/08_Hardware_Buffers - ../tutorials/09_Appendix_Tips_And_Limits + 06_Generators_And_Readouts + 07_Advanced_Generators_And_Readouts + 08_Hardware_Buffers + 09_Appendix_Tips_And_Limits .. toctree:: :maxdepth: 1 - :caption: Advanced Tutorials (10-14) + :caption: Advanced Tutorials (10-15) - ../tutorials/10_Multi_Board_Synchronization - ../tutorials/11_Streaming_And_RealTime_Processing - ../tutorials/12_DSP_Blocks_And_Correlators - ../tutorials/13_Custom_Firmware_Integration - ../tutorials/14_XCOM_Network_Synchronization - ../tutorials/README + 10_Multi_Board_Synchronization + 11_Streaming_And_RealTime_Processing + 12_DSP_Blocks_And_Correlators + 13_Custom_Firmware_Integration + 14_XCOM_Network_Synchronization + 15_QICKBox_RF_Daughtercards + README Running the Tutorials ===================== @@ -112,5 +113,5 @@ See Also ======== - :doc:`../quick_start` - Quick installation guide -- :doc:`asmv2_cheatsheet` - tProc v2 cheatsheet -- :doc:`timing` - More details on timeline management \ No newline at end of file +- :doc:`../topics/asmv2_cheatsheet` - tProc v2 cheatsheet +- :doc:`../topics/timing` - More details on timeline management From 7dd3bb7cdf9098807113268141d17b040e1e3320 Mon Sep 17 00:00:00 2001 From: Sho Uemura Date: Tue, 8 Sep 2026 19:10:37 -0500 Subject: [PATCH 17/23] organize firmware doc files a bit --- .../generators/index.rst} | 39 +++++--- .../{ => firmware/generators}/sg_int4_v2.rst | 14 +-- .../{ => firmware/generators}/sg_mixmux8.rst | 16 ++-- .../{ => firmware/generators}/sg_mux8.rst | 8 +- .../{ => firmware/generators}/sg_v4.rst | 14 +-- .../{ => firmware/generators}/sg_v6.rst | 16 ++-- .../{firmware.rst => firmware/index.rst} | 95 ++++++++++--------- .../{ => firmware/readouts}/avg_buffer.rst | 10 +- .../readouts/index.rst} | 42 +++++--- docs/source/{ => firmware/readouts}/kidsim.md | 4 +- .../{ => firmware/readouts}/mr_buffer_et.rst | 12 +-- .../readouts}/readout_dynamic.rst | 30 +++--- .../{ => firmware/readouts}/readout_pfb.rst | 32 +++---- .../{ => firmware/readouts}/readout_v2.rst | 20 ++-- docs/source/{ => firmware}/support_cores.rst | 20 ++-- docs/source/index.rst | 42 ++------ docs/source/modules.rst | 10 +- docs/source/topics/asmv2_cheatsheet.rst | 6 +- docs/source/topics/freq_matching.rst | 6 +- docs/source/topics/playing_pulses.rst | 16 ++-- docs/source/topics/readout_modes.rst | 4 +- docs/source/topics/timing.rst | 2 +- docs/source/topics/units.rst | 4 +- docs/source/tprocv1.rst | 4 +- docs/source/tprocv2_trm.rst | 34 +++---- .../15_QICKBox_RF_Daughtercards.ipynb | 4 +- 26 files changed, 254 insertions(+), 250 deletions(-) rename docs/source/{generators.rst => firmware/generators/index.rst} (80%) rename docs/source/{ => firmware/generators}/sg_int4_v2.rst (97%) rename docs/source/{ => firmware/generators}/sg_mixmux8.rst (96%) rename docs/source/{ => firmware/generators}/sg_mux8.rst (98%) rename docs/source/{ => firmware/generators}/sg_v4.rst (97%) rename docs/source/{ => firmware/generators}/sg_v6.rst (96%) rename docs/source/{firmware.rst => firmware/index.rst} (86%) rename docs/source/{ => firmware/readouts}/avg_buffer.rst (96%) rename docs/source/{readout.rst => firmware/readouts/index.rst} (83%) rename docs/source/{ => firmware/readouts}/kidsim.md (99%) rename docs/source/{ => firmware/readouts}/mr_buffer_et.rst (97%) rename docs/source/{ => firmware/readouts}/readout_dynamic.rst (95%) rename docs/source/{ => firmware/readouts}/readout_pfb.rst (95%) rename docs/source/{ => firmware/readouts}/readout_v2.rst (90%) rename docs/source/{ => firmware}/support_cores.rst (96%) diff --git a/docs/source/generators.rst b/docs/source/firmware/generators/index.rst similarity index 80% rename from docs/source/generators.rst rename to docs/source/firmware/generators/index.rst index dd1456181..f0b3ee9b2 100644 --- a/docs/source/generators.rst +++ b/docs/source/firmware/generators/index.rst @@ -5,6 +5,17 @@ Signal Generators - QICK Firmware :local: :depth: 2 +.. toctree:: + :maxdepth: 2 + :caption: 7. Signal Generators + :hidden: + + sg_v6 + sg_mux8 + sg_mixmux8 + sg_int4_v2 + sg_v4 + Overview -------- @@ -26,29 +37,29 @@ below. - Tones - Envelope - Typical use - * - :doc:`/sg_v6` + * - :doc:`sg_v6` - 1 (arbitrary shape) - Yes, full rate - The default choice for shaped pulses (Gaussian, DRAG, flat-top) -- qubit drive, readout drive. - * - :doc:`/sg_int4_v2` + * - :doc:`sg_int4_v2` - 1 (arbitrary shape) - Yes, 4x-interpolated - Same use case as SG-v6 on boards/channels where this lighter-weight core is instantiated instead; has a DAC-side mixer (``HAS_MIXER``). - * - :doc:`/sg_v4` + * - :doc:`sg_v4` - 1 (arbitrary shape) - Yes, full rate - Legacy predecessor to SG-v6; not used in any board design currently in this repository. Documented for driver/backward-compatibility reference, not for new designs. - * - :doc:`/sg_mux8` + * - :doc:`sg_mux8` - up to 8 (fixed CW) - No - Playing several simultaneous fixed tones from one channel -- e.g. a frequency comb, or driving several resonators/qubits at once without one DAC channel per tone. - * - :doc:`/sg_mixmux8` + * - :doc:`sg_mixmux8` - up to 8 (fixed CW) - No - Same as SG-Mux8, plus a shared DAC-side mixer so the whole comb can be @@ -86,21 +97,21 @@ which core is behind a given channel: declare it once with :meth:`.QickProgram.declare_gen`, define named pulses with :meth:`.QickProgram.add_pulse` (and :meth:`.QickProgram.add_envelope` first, if it needs a shape), then play them with :meth:`.QickProgram.pulse`. See -:doc:`/sg_v6`'s "Python Usage" section for worked examples (single pulse, -shaped pulse, multiple queued pulses), and :doc:`/sg_mixmux8`'s Python +:doc:`sg_v6`'s "Python Usage" section for worked examples (single pulse, +shaped pulse, multiple queued pulses), and :doc:`sg_mixmux8`'s Python section for the multiplexed-generator variant (``mux_freqs``/``mux_gains`` instead of one ``freq``/``gain`` per pulse). Related Documentation ---------------------- -* :doc:`/sg_v6` - the flagship arbitrary-envelope generator (start here) -* :doc:`/sg_int4_v2`, :doc:`/sg_v4` - other single-tone arbitrary generators -* :doc:`/sg_mux8`, :doc:`/sg_mixmux8` - multiplexed (multi-tone) generators -* :doc:`/firmware` - which generator core is on which channel, on the +* :doc:`sg_v6` - the flagship arbitrary-envelope generator (start here) +* :doc:`sg_int4_v2`, :doc:`sg_v4` - other single-tone arbitrary generators +* :doc:`sg_mux8`, :doc:`sg_mixmux8` - multiplexed (multi-tone) generators +* :doc:`../index` - which generator core is on which channel, on the reference board -* :doc:`topics/gen_config` - shared pulse configuration options +* :doc:`/topics/gen_config` - shared pulse configuration options (``outsel``/``mode``/``stdysel``) -* :doc:`topics/freq_matching` - keeping generator and readout frequencies +* :doc:`/topics/freq_matching` - keeping generator and readout frequencies in sync -* :doc:`/readout` - the readout-side counterpart to this page +* :doc:`../readouts/index` - the readout-side counterpart to this page diff --git a/docs/source/sg_int4_v2.rst b/docs/source/firmware/generators/sg_int4_v2.rst similarity index 97% rename from docs/source/sg_int4_v2.rst rename to docs/source/firmware/generators/sg_int4_v2.rst index 633bbe46c..f12ec281a 100644 --- a/docs/source/sg_int4_v2.rst +++ b/docs/source/firmware/generators/sg_int4_v2.rst @@ -7,7 +7,7 @@ Interpolated Signal Generator v2 (axis_sg_int4_v2) - QICK Firmware :depth: 2 **axis_sg_int4_v2** is a single-tone, arbitrary-envelope waveform generator. -Unlike :doc:`/sg_v6`, which runs its DDS and envelope memory at the DAC's +Unlike :doc:`sg_v6`, which runs its DDS and envelope memory at the DAC's full parallel sample rate, ``axis_sg_int4_v2`` stores the envelope at 1/4 of the output rate and reconstructs the missing samples with a **4x interpolation FIR filter** -- hence "int4". The module lives in the ``qick`` @@ -35,7 +35,7 @@ attribute is defined but not actually read anywhere else in the driver stack, so treat it as documentation rather than as something that changes behavior). -This is the key architectural difference from :doc:`/sg_v6` (and the older +This is the key architectural difference from :doc:`sg_v6` (and the older ``axis_signal_gen_v4``/``v5``, referred to together as SG-v4/v5/v6 in the Python driver): SG-v6 stores the envelope **pre-expanded**, with one BRAM pair (real/imag) per parallel DDS lane (``N_DDS`` pairs, default 16), so @@ -55,7 +55,7 @@ via its own DDS + envelope multiplier) -- it is not multiplexed like ``axis_sg_mux4_v1``, which drives several simultaneous tones from one channel. -.. figure:: images/firmware/sg_int4_v2-blocks.svg +.. figure:: /images/firmware/sg_int4_v2-blocks.svg :align: center :width: 80% @@ -378,14 +378,14 @@ an envelope loaded with :meth:`.QickProgram.add_envelope`). Related Documentation -------------------------------------------------------------------- -* :doc:`/sg_v6` -- SG-v6, the full-rate/full-BRAM sibling generator this +* :doc:`sg_v6` -- SG-v6, the full-rate/full-BRAM sibling generator this page repeatedly compares against. * :doc:`/tprocv2_trm` -- tProcessor v2 sequencing (``WPORT_WR``/``add_pulse`` path that ultimately fills this generator's ``S1_AXIS`` via ``qick_sg_translator``). -* :doc:`/firmware` -- Firmware overview and channel assignments. -* :doc:`topics/gen_config` -- ``outsel``/``mode``/``stdysel`` semantics +* :doc:`../index` -- Firmware overview and channel assignments. +* :doc:`/topics/gen_config` -- ``outsel``/``mode``/``stdysel`` semantics (shared across all pulsed generators in this doc set). -* :doc:`topics/freq_matching` -- keeping generator and readout frequencies +* :doc:`/topics/freq_matching` -- keeping generator and readout frequencies in sync (relevant here because of the required ``mixer_freq``). * `axis_sg_int4_v2 source code `_ diff --git a/docs/source/sg_mixmux8.rst b/docs/source/firmware/generators/sg_mixmux8.rst similarity index 96% rename from docs/source/sg_mixmux8.rst rename to docs/source/firmware/generators/sg_mixmux8.rst index 5c879cdc2..da90121cb 100644 --- a/docs/source/sg_mixmux8.rst +++ b/docs/source/firmware/generators/sg_mixmux8.rst @@ -7,7 +7,7 @@ Multiplexed Signal Generator with Mixer (axis_sg_mixmux8_v1) - QICK Firmware :depth: 2 **axis_sg_mixmux8_v1** is an 8-tone multiplexed (muxed) signal generator, -almost identical in its control logic to :doc:`/sg_mux8` +almost identical in its control logic to :doc:`sg_mux8` (``axis_sg_mux8_v1``), but with a **complex (I/Q) datapath** so that its output can drive the RFDC's own digital mixer/NCO. The module lives under ``firmware/ip/axis_sg_mixmux8_v1/`` and is exposed to Python through @@ -93,7 +93,7 @@ up (or down) in frequency, which is what lets ``axis_sg_mixmux8_v1`` (unlike ``axis_sg_mux8_v1``) place its whole multi-tone output away from DC, including outside the DAC's first Nyquist zone. -.. figure:: images/firmware/sg_mixmux8-blocks.svg +.. figure:: /images/firmware/sg_mixmux8-blocks.svg :align: center :width: 85% @@ -109,7 +109,7 @@ including outside the DAC's first Nyquist zone. The RFDC mixer/NCO itself (register layout, valid frequency ranges, Nyquist-zone handling) lives in AMD's RF Data Converter IP and the ``qick.qick.AxisRFDC``-family driver, not in this IP -- see - :doc:`topics/freq_matching` for the software-level picture of how + :doc:`/topics/freq_matching` for the software-level picture of how generator and readout frequencies are kept consistent. -------------------------------------------------------------------- @@ -137,7 +137,7 @@ including outside the DAC's first Nyquist zone. There is no synthesis parameter that changes the mixer/complex behavior -- that is hard-wired into the ``dds_compiler_0`` IP core configuration (``Output_Selection = "Sine_and_Cosine"``), unlike ``ENVELOPE_TYPE`` or -``GEN_DDS`` on the arbitrary-waveform generators (:doc:`/sg_v6`). +``GEN_DDS`` on the arbitrary-waveform generators (:doc:`sg_v6`). -------------------------------------------------------------------- 3. Datapath @@ -357,12 +357,12 @@ this one, :meth:`.QickProgram.config_gens` calls it for you from the Related Documentation -------------------------------------------------------------------- -* :doc:`/sg_mux8` -- the real-valued (no DAC mixer) counterpart to this IP; +* :doc:`sg_mux8` -- the real-valued (no DAC mixer) counterpart to this IP; read that page first for the parts of the datapath (FIFO, control FSM, adder tree, quantization) that are shared verbatim. -* :doc:`/sg_v6` -- the arbitrary-envelope (non-muxed) signal generator, for +* :doc:`sg_v6` -- the arbitrary-envelope (non-muxed) signal generator, for comparison with a different generator family. -* :doc:`topics/freq_matching` -- keeping generator and readout frequencies +* :doc:`/topics/freq_matching` -- keeping generator and readout frequencies (including the shared mixer frequency) consistent. -* :doc:`/readout` -- readout system overview, including the readout-side +* :doc:`../readouts/index` -- readout system overview, including the readout-side digital mixer that this generator's frequency is often matched against. diff --git a/docs/source/sg_mux8.rst b/docs/source/firmware/generators/sg_mux8.rst similarity index 98% rename from docs/source/sg_mux8.rst rename to docs/source/firmware/generators/sg_mux8.rst index b2c3aac4c..f6425e23d 100644 --- a/docs/source/sg_mux8.rst +++ b/docs/source/firmware/generators/sg_mux8.rst @@ -8,7 +8,7 @@ Signal Generator Mux8 (axis_sg_mux8_v1) - QICK Firmware **axis_sg_mux8_v1** is a fixed-tone, 8-way multiplexed signal generator: it plays up to 8 simultaneous, independently-configured DDS tones per channel, -as opposed to the single-tone arbitrary generators (:doc:`/sg_v6` and its +as opposed to the single-tone arbitrary generators (:doc:`sg_v6` and its siblings) which play one tone at a time but can shape it with an arbitrary envelope. There is no envelope memory here -- a "pulse" on this generator is just "play some subset of the 8 pre-programmed tones for N samples". The @@ -56,7 +56,7 @@ tones rather than 8, and (for V1/V2) drive a DAC-side digital mixer (``AxisSgMux8V1.HAS_MIXER = False`` -- see the Python Interface section). The mux4 RTL is out of scope for this document. -.. figure:: images/firmware/sg_mux8-blocks.svg +.. figure:: /images/firmware/sg_mux8-blocks.svg :align: center :width: 85% @@ -336,10 +336,10 @@ zeroes the gain of any unconfigured tone up to ``N_TONES``, then pulses Related Documentation -------------------------------------------------------------------- -* :doc:`/sg_v6` -- the single-tone arbitrary-envelope generator, for +* :doc:`sg_v6` -- the single-tone arbitrary-envelope generator, for contrast with this fixed-tone mux design. * :doc:`/tprocv2_trm` -- tProcessor v2 instruction reference, including the wave-descriptor mechanism translated by ``sg_translator`` into this core's mask/length format. -* :doc:`/firmware` -- firmware overview and channel assignments. +* :doc:`../index` -- firmware overview and channel assignments. * `axis_sg_mux8_v1 source code `_ diff --git a/docs/source/sg_v4.rst b/docs/source/firmware/generators/sg_v4.rst similarity index 97% rename from docs/source/sg_v4.rst rename to docs/source/firmware/generators/sg_v4.rst index 37d89920c..e4f2ea77a 100644 --- a/docs/source/sg_v4.rst +++ b/docs/source/firmware/generators/sg_v4.rst @@ -9,7 +9,7 @@ Signal Generator v4 (SG-v4) - QICK Firmware **axis_signal_gen_v4** is QICK's original tProc-controlled arbitrary-waveform generator: a single real-valued output lane fed by ``N_DDS`` parallel DDS-plus-mixer channels, each pairing one complex multiplier with its own -envelope BRAM. It is the direct predecessor of :doc:`/sg_v6`, and the two +envelope BRAM. It is the direct predecessor of :doc:`sg_v6`, and the two share the same Python driver class (``qick.drivers.generator.AxisSignalGen``) -- its docstring states plainly that the class "Supports AxisSignalGen V4+V5+V6, since they have the same software interface (ignoring registers @@ -51,7 +51,7 @@ Two source files in ``firmware/ip/axis_signal_gen_v4/src/`` -- ``dither.v`` and ``random_gen.v`` -- are **not part of the active datapath**; see :ref:`sgv4-dithering` below. -.. figure:: images/firmware/sg_v4-blocks.svg +.. figure:: /images/firmware/sg_v4-blocks.svg :align: center :width: 85% @@ -81,7 +81,7 @@ and ``random_gen.v`` -- are **not part of the active datapath**; see 65536 samples total across the interleaved lanes -- this is what the Python driver reports as ``cfg['maxlen']`` (``2**N * N_DDS``, in ``AxisSignalGen._init_config``). SG-v6's top-level default for the - same parameter is ``N = 16`` (see :doc:`/sg_v6`); the value actually + same parameter is ``N = 16`` (see :doc:`sg_v6`); the value actually burned into a given bitstream depends on how the block design instantiated the core, so read ``soc.gens[i]['maxlen']`` at runtime rather than assuming either default. @@ -113,7 +113,7 @@ SG-v6 -- see :ref:`sgv4-vs-sgv6`). Correspondingly, 16-entry, 160-bit-wide FIFO (``fifo.vhd``, ``.B(160)``, ``.N(16)``) with ``fifo_wr_en = s1_axis_tvalid`` and ``s1_axis_tready = ~fifo_full`` -- there is no register staging on the write side, unlike ``axis_readout_v2``'s -``WE_REG``-pulsed descriptor push (:doc:`/readout_v2`). ``ctrl.sv`` decodes +``WE_REG``-pulsed descriptor push (:doc:`../readouts/readout_v2`). ``ctrl.sv`` decodes the descriptor at the head of the FIFO: .. list-table:: Waveform descriptor fields (``ctrl.sv`` header comment) @@ -462,10 +462,10 @@ register through the low-level MMIO interface yourself. Related Documentation -------------------------------------------------------------------- -* :doc:`/sg_v6` -- the successor core; see :ref:`sgv4-vs-sgv6` above for +* :doc:`sg_v6` -- the successor core; see :ref:`sgv4-vs-sgv6` above for the concrete RTL differences. * :doc:`/tprocv2_trm` -- tProcessor sequencing/triggering that queues waveform descriptors into this core's ``s1_axis``. -* :doc:`/firmware` -- firmware overview and channel assignments. -* :doc:`/readout_v2` -- a similarly-legacy, single-tone predecessor core on +* :doc:`../index` -- firmware overview and channel assignments. +* :doc:`../readouts/readout_v2` -- a similarly-legacy, single-tone predecessor core on the readout (ADC) side, for comparison. diff --git a/docs/source/sg_v6.rst b/docs/source/firmware/generators/sg_v6.rst similarity index 96% rename from docs/source/sg_v6.rst rename to docs/source/firmware/generators/sg_v6.rst index 67328d41e..a48492ee4 100644 --- a/docs/source/sg_v6.rst +++ b/docs/source/firmware/generators/sg_v6.rst @@ -35,7 +35,7 @@ And two envelope types: * **COMPLEX** (``ENVELOPE_TYPE = "COMPLEX"``): separate memories for real and imaginary parts. * **REAL** (``ENVELOPE_TYPE = "REAL"``): real part only; the imaginary part is forced to zero. -.. figure:: images/firmware/sg_v6-blocks.svg +.. figure:: /images/firmware/sg_v6-blocks.svg :align: center :width: 80% @@ -293,7 +293,7 @@ blocks are instantiated. always uses. It is **not** simply "tProc channel - 1": which tProc waveform port and DAC each array index maps to is board-specific and, on some boards, not a 1:1 mapping at all (see the worked ZCU216 example in -:doc:`/firmware`'s :ref:`tproc-zcu216-example`). Normal programs never need +:doc:`../index`'s :ref:`tproc-zcu216-example`). Normal programs never need to know this mapping -- declare the channel once by its ``soc.gens[]`` index, register any envelopes, add named pulses, then play them by name at whatever time you choose. @@ -440,7 +440,7 @@ envelope chaining, advanced tProc sequencing), refer to: - **QICK Tutorial Notebooks**: :doc:`/tutorials/06_Generators_And_Readouts`, :doc:`/tutorials/07_Advanced_Generators_And_Readouts` - **tProcessor Documentation**: :doc:`/tprocv2_trm` -- **Firmware Overview**: :doc:`/firmware` +- **Firmware Overview**: :doc:`../index` - **Community Examples**: Check the `#qick` channel on the Unitary Fund Discord -------------------------------------------------------------------- @@ -506,10 +506,10 @@ envelope chaining, advanced tProc sequencing), refer to: Related Documentation -------------------------------------------------------------------- -* :doc:`/generators` - overview of all QICK signal generator types and when to use each +* :doc:`index` - overview of all QICK signal generator types and when to use each * :doc:`/tprocv2_trm` - tProcessor v2 for sequencing and triggering -* :doc:`/firmware` - Firmware overview and channel assignments -* :doc:`/sg_mux8`, :doc:`/sg_mixmux8` - multi-tone generators, for playing several simultaneous fixed tones instead of one arbitrary-envelope pulse -* :doc:`/sg_int4_v2` - a lighter single-tone arbitrary generator (see :doc:`/generators` for the tradeoffs) -* :doc:`/sg_v4` - the legacy predecessor to SG-v6 +* :doc:`../index` - Firmware overview and channel assignments +* :doc:`sg_mux8`, :doc:`sg_mixmux8` - multi-tone generators, for playing several simultaneous fixed tones instead of one arbitrary-envelope pulse +* :doc:`sg_int4_v2` - a lighter single-tone arbitrary generator (see :doc:`index` for the tradeoffs) +* :doc:`sg_v4` - the legacy predecessor to SG-v6 * `SG-v6 source code `_ diff --git a/docs/source/firmware.rst b/docs/source/firmware/index.rst similarity index 86% rename from docs/source/firmware.rst rename to docs/source/firmware/index.rst index a326415a9..637a9d868 100644 --- a/docs/source/firmware.rst +++ b/docs/source/firmware/index.rst @@ -1,6 +1,15 @@ Firmware ======== +.. toctree:: + :maxdepth: 2 + :caption: 5. Firmware + :hidden: + + generators/index + readouts/index + support_cores + This page provides an overview of the QICK firmware components. System Overview @@ -23,15 +32,15 @@ The QICK firmware includes the following components: - :doc:`/tprocv2_trm` * - Signal generators - Board-dependent -- each board's standard firmware provisions its own - mix of :doc:`/sg_v6`, :doc:`/sg_int4_v2`, :doc:`/sg_mixmux8`, - :doc:`/sg_mux8`; see :ref:`std-firmware-per-board` - - :doc:`/generators`, :doc:`/sg_v6` + mix of :doc:`generators/sg_v6`, :doc:`generators/sg_int4_v2`, :doc:`generators/sg_mixmux8`, + :doc:`generators/sg_mux8`; see :ref:`std-firmware-per-board` + - :doc:`generators/index`, :doc:`generators/sg_v6` * - Readouts - - Board-dependent -- single-tone (:doc:`/readout_v2`, - :doc:`/readout_dynamic`) and/or channelized (:doc:`/readout_pfb`); + - Board-dependent -- single-tone (:doc:`readouts/readout_v2`, + :doc:`readouts/readout_dynamic`) and/or channelized (:doc:`readouts/readout_pfb`); see :ref:`std-firmware-per-board` - - :doc:`/readout`, :doc:`/readout_dynamic`, :doc:`/readout_pfb`, - :doc:`/avg_buffer` + - :doc:`readouts/index`, :doc:`readouts/readout_dynamic`, :doc:`readouts/readout_pfb`, + :doc:`readouts/avg_buffer` * - tProc trigger outputs (``trig_N_o`` pins) - Board-dependent single-bit pins -- PMOD bits plus one per averaging buffer, plus DDR4/multi-rate-buffer triggers where present; see @@ -42,7 +51,7 @@ Sampling frequency of ADC blocks is given by the variable ``soc.fs_adc``. Sampling frequency of DACs is stored in variable ``soc.fs_dac``. Fast-speed buffers were removed to save memory space. Raw data can be captured after x8 down-sampling. -.. figure:: images/firmware/firmware-overview.svg +.. figure:: /images/firmware/firmware-overview.svg :align: center :width: 85% @@ -62,22 +71,22 @@ Output channels driving DACs use the **Signal Generator v6**, which has the foll * 16 parallel samples per clock cycle (256-bit output bus) * Maximum envelope length: 65536 samples per channel -For complete documentation, see :doc:`/sg_v6`. If your board uses a +For complete documentation, see :doc:`generators/sg_v6`. If your board uses a different generator core (multiplexed, interpolated, or the legacy v4), see -:doc:`/generators` for the full family and which one fits which experiment. +:doc:`generators/index` for the full family and which one fits which experiment. Readout System -------------- QICK ships several readout IP variants for the DDC/decimation stage -- -:doc:`/readout_v2` (PYNQ-register-configured, single tone), -:doc:`/readout_dynamic` (``axis_readout_v3``/``axis_dyn_readout_v1``, -tProc-configured per shot, single tone), and :doc:`/readout_pfb` +:doc:`readouts/readout_v2` (PYNQ-register-configured, single tone), +:doc:`readouts/readout_dynamic` (``axis_readout_v3``/``axis_dyn_readout_v1``, +tProc-configured per shot, single tone), and :doc:`readouts/readout_pfb` (``axis_pfb_readout_v2``/``v3``/``v4``, a fixed polyphase-filter-bank channelizer that fans one ADC input out to several simultaneous demodulated channels). Which one(s) a given board's standard firmware uses, and how many, is a per-board decision -- see :ref:`std-firmware-per-board`. All variants -feed the same downstream block, **Average + Buffer** (:doc:`/avg_buffer`): +feed the same downstream block, **Average + Buffer** (:doc:`readouts/avg_buffer`): **Readout Block** (architecture varies by variant -- see the pages above): @@ -94,9 +103,9 @@ feed the same downstream block, **Average + Buffer** (:doc:`/avg_buffer`): channel-numbered AXI-Stream space as the readout's own configuration; see :ref:`tproc-ports` -For complete documentation, see :doc:`/readout_v2`, :doc:`/readout_dynamic`, -and :doc:`/readout_pfb` (the DDC/decimation stage, in its several variants) -and :doc:`/avg_buffer` (the averaged/raw buffer IP and its register map). +For complete documentation, see :doc:`readouts/readout_v2`, :doc:`readouts/readout_dynamic`, +and :doc:`readouts/readout_pfb` (the DDC/decimation stage, in its several variants) +and :doc:`readouts/avg_buffer` (the averaged/raw buffer IP and its register map). The tProcessor v2 ----------------- @@ -107,7 +116,7 @@ It runs user-written programs that control waveform generation, data acquisition For **complete documentation**, see: * :doc:`/tprocv2_trm` - Full reference manual (architecture, instruction set, programming examples) -* :doc:`topics/asmv2_cheatsheet` - Quick reference for assembly programming +* :doc:`/topics/asmv2_cheatsheet` - Quick reference for assembly programming **Quick links to tProcessor topics:** @@ -137,14 +146,14 @@ rather than assumed: :widths: 18 10 12 12 10 12 12 10 12 * - Board (``tpv2_std`` unless noted) - - :doc:`/sg_v6` - - :doc:`/sg_int4_v2` - - :doc:`/sg_mixmux8` - - :doc:`/sg_mux8` - - :doc:`/readout_dynamic` (dyn v1) - - :doc:`/readout_pfb` (v4) - - :doc:`/avg_buffer` - - :doc:`/mr_buffer_et` + - :doc:`generators/sg_v6` + - :doc:`generators/sg_int4_v2` + - :doc:`generators/sg_mixmux8` + - :doc:`generators/sg_mux8` + - :doc:`readouts/readout_dynamic` (dyn v1) + - :doc:`readouts/readout_pfb` (v4) + - :doc:`readouts/avg_buffer` + - :doc:`readouts/mr_buffer_et` * - ZCU111 (``firmware/Top/111``) - 8 - 0 @@ -248,7 +257,7 @@ numbers). * - ``trig_0_o`` .. ``trig_7_o`` - ``PMOD0_0_LS`` .. ``PMOD0_7_LS`` (all 8 PMOD0 bits) * - ``trig_8_o`` - - ``mr_buffer_et_0/trigger`` (see :doc:`/mr_buffer_et`) + - ``mr_buffer_et_0/trigger`` (see :doc:`readouts/mr_buffer_et`) * - ``trig_9_o`` - ``ddr4/trigger`` (DDR4 streaming capture) * - ``trig_10_o`` .. ``trig_19_o`` @@ -413,7 +422,7 @@ same-width streams -- it is a clock-domain-crossing bridge, confirmed by tracing each instance's ``aclk`` nets in this board's .tcl (input side tied to the tProc core clock, output side tied to the destination tile's own clock). It is **not** part of the ``xcom`` multi-board synchronization -mechanism (:doc:`topics/xcom`) despite the similar name -- that is a wholly +mechanism (:doc:`/topics/xcom`) despite the similar name -- that is a wholly separate IP block with its own network/serial interface. Both CDC instances on this board exist purely because DAC tile 0 and the ADC-tile-2-clocked readout logic run on clocks independent of the tProc's own core clock, not @@ -437,7 +446,7 @@ capture path, letting software pick which one of the 10 channels streams to DDR4. Separately, the two dynamic readouts' *undecimated* outputs (``m0_axis``) feed a 2-input switch (``axis_switch_mr``) into the single shared ``mr_buffer_et_0`` instance. This matches, and was cross-checked -against, the independently-traced fan-out in :doc:`/readout_pfb`'s +against, the independently-traced fan-out in :doc:`readouts/readout_pfb`'s ":ref:`readout-pfb-zcu216`" section. Checking Your Own Board's Configuration @@ -453,9 +462,9 @@ your setup. Instead, read them from the running system: is *not* guaranteed to equal the tProc waveform-port number -- see :ref:`tproc-zcu216-example` for why that mapping can be non-trivial). * ``soc.readouts`` -- list of readout drivers (mix of - :doc:`/readout_v2`/:doc:`/readout_dynamic`/:doc:`/readout_pfb` types, + :doc:`readouts/readout_v2`/:doc:`readouts/readout_dynamic`/:doc:`readouts/readout_pfb` types, board-dependent). -* ``soc.avg_bufs`` -- list of :doc:`/avg_buffer` drivers. +* ``soc.avg_bufs`` -- list of :doc:`readouts/avg_buffer` drivers. * ``print(soccfg)`` -- full human-readable dump of the board's configuration, including per-channel generator/readout types and every buffer's ``avg_maxlen``/``buf_maxlen``. @@ -489,13 +498,13 @@ Firmware Parameters - Value * - Pulse memory length (per SG-v6) - 65536 samples ×2 (I/Q) = 128k total (``N=16`` default -- see - :doc:`/sg_v6`) + :doc:`generators/sg_v6`) * - Decimated ADC buffer - Board-dependent, ``2**N_BUF`` samples per component (I,Q) -- see - :doc:`/avg_buffer` + :doc:`readouts/avg_buffer` * - Accumulated ADC buffer - Board-dependent, ``2**N_AVG`` samples per component (I,Q) -- see - :doc:`/avg_buffer` + :doc:`readouts/avg_buffer` * - tProc v2 program/data memory - Synthesis parameters (``PMEM_AW``/``DMEM_AW``), board-dependent -- see :doc:`/tprocv2_trm` @@ -512,13 +521,13 @@ Related Documentation --------------------- * :doc:`/tprocv2_trm` - Complete tProcessor v2 reference manual -* :doc:`/generators` - Full generator-core family (SG-v6, SG-int4-v2, SG-mixmux8, SG-mux8) -* :doc:`/sg_v6` - Signal Generator v6 documentation -* :doc:`/readout` - Readout system overview -* :doc:`/readout_dynamic` - tProc-configured single-tone readouts (axis_readout_v3 / axis_dyn_readout_v1) -* :doc:`/readout_pfb` - Polyphase-filter-bank channelized readouts (axis_pfb_readout_v2/v3/v4) -* :doc:`/avg_buffer` - Averaged/raw buffer IP downstream of every readout variant -* :doc:`/mr_buffer_et` - Multi-rate buffer (DDR4/streaming) shared readout path -* :doc:`topics/asmv2_cheatsheet` - tProc v2 assembly quick reference -* :doc:`tutorials/index` - tProc v2 tutorial examples +* :doc:`generators/index` - Full generator-core family (SG-v6, SG-int4-v2, SG-mixmux8, SG-mux8) +* :doc:`generators/sg_v6` - Signal Generator v6 documentation +* :doc:`readouts/index` - Readout system overview +* :doc:`readouts/readout_dynamic` - tProc-configured single-tone readouts (axis_readout_v3 / axis_dyn_readout_v1) +* :doc:`readouts/readout_pfb` - Polyphase-filter-bank channelized readouts (axis_pfb_readout_v2/v3/v4) +* :doc:`readouts/avg_buffer` - Averaged/raw buffer IP downstream of every readout variant +* :doc:`readouts/mr_buffer_et` - Multi-rate buffer (DDR4/streaming) shared readout path +* :doc:`/topics/asmv2_cheatsheet` - tProc v2 assembly quick reference +* :doc:`/tutorials/index` - tProc v2 tutorial examples * `Signal Generator v6 source `_ diff --git a/docs/source/avg_buffer.rst b/docs/source/firmware/readouts/avg_buffer.rst similarity index 96% rename from docs/source/avg_buffer.rst rename to docs/source/firmware/readouts/avg_buffer.rst index d47ffa3e5..68ab819c0 100644 --- a/docs/source/avg_buffer.rst +++ b/docs/source/firmware/readouts/avg_buffer.rst @@ -7,11 +7,11 @@ Averager + Buffer (axis_avg_buffer) - QICK Firmware :depth: 2 The **Averager + Buffer** (``axis_avg_buffer``) is the IP block that sits -downstream of a readout (:doc:`/readout`) and turns its decimated I/Q stream +downstream of a readout (:doc:`index`) and turns its decimated I/Q stream into the two kinds of data a QICK program can pull back over PS-PL DMA: accumulated points (:meth:`.AcquireMixin.acquire`) and raw decimated waveforms (:meth:`.AcquireMixin.acquire_decimated`) -- see -:doc:`topics/readout_modes` for the software-level distinction. The module +:doc:`/topics/readout_modes` for the software-level distinction. The module lives in the ``qick`` firmware repository under ``firmware/ip/axis_avg_buffer/`` and is exposed to Python through ``qick.drivers.readout.AxisAvgBuffer`` (and its ``V1pt1``/``V1pt2``/ @@ -228,10 +228,10 @@ extra samples and discarding them. Related Documentation ---------------------- -* :doc:`/readout` -- the readout block that feeds this buffer's ``s_axis``. -* :doc:`topics/readout_modes` -- ``acquire()`` vs. ``acquire_decimated()``. +* :doc:`index` -- the readout block that feeds this buffer's ``s_axis``. +* :doc:`/topics/readout_modes` -- ``acquire()`` vs. ``acquire_decimated()``. * :doc:`/tprocv2_trm` -- the tProcessor trigger that starts a capture, and the m2_axis feedback port. -* :doc:`/mr_buffer_et` -- the alternate multi-rate buffer used for +* :doc:`mr_buffer_et` -- the alternate multi-rate buffer used for DDR4/streaming readout of the *undecimated* data stream, as opposed to this block's decimated raw buffer. diff --git a/docs/source/readout.rst b/docs/source/firmware/readouts/index.rst similarity index 83% rename from docs/source/readout.rst rename to docs/source/firmware/readouts/index.rst index 83dba230d..fd5f4b9d3 100644 --- a/docs/source/readout.rst +++ b/docs/source/firmware/readouts/index.rst @@ -5,6 +5,18 @@ Readout System - QICK Firmware :local: :depth: 2 +.. toctree:: + :maxdepth: 2 + :caption: 6. Readout System + :hidden: + + readout_v2 + readout_dynamic + readout_pfb + avg_buffer + mr_buffer_et + kidsim + Overview -------- @@ -15,10 +27,10 @@ The QICK readout system is built around two main IP blocks: The readout process is triggered by a dedicated single-bit ``trig_N_o`` pin from the tProcessor (one per averaging buffer instance -- see -:ref:`tproc-ports` in :doc:`/firmware` for the full pin model) and can be +:ref:`tproc-ports` in :doc:`../index` for the full pin model) and can be configured for raw sample capture or coherent averaging. -.. figure:: ../../graphics/qsystem-readout.svg +.. figure:: ../../../../graphics/qsystem-readout.svg :width: 100% :align: center @@ -68,17 +80,17 @@ This block receives the decimated data stream and can: - Value * - Raw buffer length - Board-dependent, ``2**N_BUF`` samples per component (I/Q) -- see - :doc:`/avg_buffer` + :doc:`avg_buffer` * - Accumulated buffer length - Board-dependent, ``2**N_AVG`` samples per component (I/Q) -- see - :doc:`/avg_buffer` + :doc:`avg_buffer` * - Trigger source - One dedicated ``trig_N_o`` pin per buffer instance, *not* a bit within a channel-numbered data word -- see :ref:`tproc-ports` in - :doc:`/firmware` + :doc:`../index` The buffer IP that stores/accumulates this data (registers, DMA transfer, -edge-counter mode) is documented separately in :doc:`/avg_buffer`. +edge-counter mode) is documented separately in :doc:`avg_buffer`. Python Interface ---------------- @@ -95,7 +107,7 @@ The workflow, inside a :class:`.QickProgram` (e.g. an 3. After running the program, pull the data back with :meth:`.AcquireMixin.acquire` (accumulated) or :meth:`.AcquireMixin.acquire_decimated` (raw waveform) -- see - :doc:`topics/readout_modes` for which one to use. + :doc:`/topics/readout_modes` for which one to use. .. code-block:: python @@ -129,7 +141,7 @@ The workflow, inside a :class:`.QickProgram` (e.g. an The readout and buffer are still reachable directly, as ``soc.readouts[i]`` and ``soc.avg_bufs[i]``, for debugging or hand-rolled acquisition outside -the ``acquire()``/``acquire_decimated()`` flow -- see :doc:`/avg_buffer`'s +the ``acquire()``/``acquire_decimated()`` flow -- see :doc:`avg_buffer`'s Python Interface section for the buffer-level ``config_avg``/ ``transfer_avg``/``config_buf``/``transfer_buf`` calls this normally sits on top of. :meth:`.AbsReadout.set_all`/``set_all_int`` on the readout driver @@ -150,7 +162,7 @@ Hardware Considerations the reference board, i.e. 2k total samples) - Average mode: up to ``soc.cfg['readouts'][i]['avg_maxlen']`` I/Q pairs (16384 on the reference board, i.e. 32k total) -- read these from your own - board's config rather than assuming a number, see :doc:`/avg_buffer`. + board's config rather than assuming a number, see :doc:`avg_buffer`. **Example: Calculating acquisition time** @@ -166,12 +178,12 @@ Hardware Considerations Related Documentation --------------------- -* :doc:`/avg_buffer` - the averaged/raw buffer IP downstream of this readout -* :doc:`/readout_pfb` - the polyphase-filter-bank multi-channel readout +* :doc:`avg_buffer` - the averaged/raw buffer IP downstream of this readout +* :doc:`readout_pfb` - the polyphase-filter-bank multi-channel readout variant (``axis_pfb_readout_v2``/``v3``/``v4``), which channelizes into several simultaneous demod outputs instead of one tunable frequency -* :doc:`topics/readout_modes` - ``acquire()`` vs. ``acquire_decimated()`` +* :doc:`/topics/readout_modes` - ``acquire()`` vs. ``acquire_decimated()`` * :doc:`/tprocv2_trm` - tProcessor v2 for triggering and sequencing -* :doc:`/firmware` - Firmware overview and channel assignments -* :doc:`topics/timing` - Timing considerations for readout -* :doc:`topics/freq_matching` - Frequency matching between generators and readouts +* :doc:`../index` - Firmware overview and channel assignments +* :doc:`/topics/timing` - Timing considerations for readout +* :doc:`/topics/freq_matching` - Frequency matching between generators and readouts diff --git a/docs/source/kidsim.md b/docs/source/firmware/readouts/kidsim.md similarity index 99% rename from docs/source/kidsim.md rename to docs/source/firmware/readouts/kidsim.md index ce29e76fb..e4cae4645 100644 --- a/docs/source/kidsim.md +++ b/docs/source/firmware/readouts/kidsim.md @@ -33,7 +33,7 @@ configuration (DDS/IIR/output-select/puncturing registers) is written through a shared register set and latched into the target lane by writing `ADDR_REG` (the lane index) then pulsing `WE_REG`. -```{figure} images/firmware/kidsim-blocks.svg +```{figure} /images/firmware/kidsim-blocks.svg :align: center :width: 90% @@ -477,7 +477,7 @@ measured numbers: ## Related Documentation -* {doc}`/readout` and {doc}`/avg_buffer` -- the real readout chain this IP +* {doc}`index` and {doc}`avg_buffer` -- the real readout chain this IP emulates a resonator in front of, for hardware-in-the-loop testing. * `firmware/fusesoc/cores/ip/axis_kidsim_v3/model/kidsim_resonator_demo.ipynb` -- Python behavioral model / demo notebook. diff --git a/docs/source/mr_buffer_et.rst b/docs/source/firmware/readouts/mr_buffer_et.rst similarity index 97% rename from docs/source/mr_buffer_et.rst rename to docs/source/firmware/readouts/mr_buffer_et.rst index ff80163bf..07fe2cc15 100644 --- a/docs/source/mr_buffer_et.rst +++ b/docs/source/firmware/readouts/mr_buffer_et.rst @@ -10,7 +10,7 @@ The **Multi-Rate buffer with External Trigger** (``mr_buffer_et``) is a small on-chip capture buffer that taps a readout's *undecimated* data stream -- the downconverted but not-yet-decimated samples, straight out of the digital mixer, before the readout's FIR/decimate-by-N stage. This is in -contrast to :doc:`/avg_buffer`'s raw buffer and the DDR4 buffer +contrast to :doc:`avg_buffer`'s raw buffer and the DDR4 buffer (``axis_buffer_ddr_v1``), which both see the *decimated* stream. Because it sits upstream of decimation, ``mr_buffer_et`` sees the full ADC-rate signal (useful for looking at spurs, noise, or transient/settling behavior that @@ -80,7 +80,7 @@ In board designs (see e.g. (``axis_switch_mr``) whose inputs are the ``m0_axis`` ports of the board's dynamic readouts (``axis_dyn_readout_v1``) -- the undecimated tap; compare with the ``m1_axis`` port of the same readouts, which is the decimated -stream that feeds :doc:`/avg_buffer`. Its own ``m00_axis`` output feeds an +stream that feeds :doc:`avg_buffer`. Its own ``m00_axis`` output feeds an AXI-DMA (``axi_dma_mr``) that drains captured data to PS-side (CPU) memory. In that same board design the instance is parameterized with ``B=32`` (a packed 16-bit I / 16-bit Q sample) and ``N=10`` (1024-deep @@ -133,7 +133,7 @@ also how the Python driver computes it -- see Section 5). 3. Datapath -------------------------------------------------------------------- -.. figure:: images/firmware/mr_buffer_et-blocks.svg +.. figure:: /images/firmware/mr_buffer_et-blocks.svg :align: center :width: 85% @@ -385,10 +385,10 @@ the ``TOTAL_WORDS`` quantity from Section 3.2. Related Documentation -------------------------------------------------------------------- -* :doc:`/avg_buffer` -- the buffer that captures the *decimated* stream +* :doc:`avg_buffer` -- the buffer that captures the *decimated* stream from the same readouts (accumulated and raw-decimated modes); ``mr_buffer_et`` instead captures the undecimated stream. -* :doc:`/readout_v2` and :doc:`/readout_dynamic` -- the readouts whose +* :doc:`readout_v2` and :doc:`readout_dynamic` -- the readouts whose undecimated output (``m0_axis`` on the dynamic readouts) feeds this block via ``axis_switch_mr``. * :doc:`/tprocv2_trm` -- the tProcessor trigger port that starts a @@ -401,7 +401,7 @@ Related Documentation buffer block and is easy to confuse with ``mr_buffer_et``, but the two are quite different. Per its own driver docstring, ``AxisBufferDdrV1`` "is fed by the downconverted+decimated data stream coming out of the - readout" -- i.e. the *same* stream that feeds :doc:`/avg_buffer`, not + readout" -- i.e. the *same* stream that feeds :doc:`avg_buffer`, not the undecimated stream ``mr_buffer_et`` sees -- and it streams continuously into off-chip DDR4 memory (via an AXI memory-mapped port, ``rstart_reg``/``wstart_reg``/``wnburst_reg`` etc.) rather than a small diff --git a/docs/source/readout_dynamic.rst b/docs/source/firmware/readouts/readout_dynamic.rst similarity index 95% rename from docs/source/readout_dynamic.rst rename to docs/source/firmware/readouts/readout_dynamic.rst index 568677d9c..9b9898b63 100644 --- a/docs/source/readout_dynamic.rst +++ b/docs/source/firmware/readouts/readout_dynamic.rst @@ -7,8 +7,8 @@ Dynamic Readouts (axis_readout_v3 / axis_dyn_readout_v1) - QICK Firmware :depth: 2 **axis_readout_v3** and **axis_dyn_readout_v1** are the *dynamic* counterparts -of :doc:`/readout_v2`: digital down-converter (DDC) IP blocks that sit -between the RFDC's ADC output and :doc:`/avg_buffer`, but whose +of :doc:`readout_v2`: digital down-converter (DDC) IP blocks that sit +between the RFDC's ADC output and :doc:`avg_buffer`, but whose frequency/phase/output-selection/length are set **by the tProcessor, in real time, once per shot**, instead of being written ahead of time as PYNQ registers from software. Both modules live under ``firmware/ip/`` (in @@ -49,13 +49,13 @@ itself, rather than once via a PYNQ register write before the program starts. outputs: ``m0_axis``, the down-converted-but-not-yet-decimated stream (8 complex samples/clock, still subject to the output-selection mux), and ``m1_axis``, the final decimated stream (1 complex sample/clock) that feeds - :doc:`/avg_buffer`. + :doc:`avg_buffer`. Both are single-tone readouts (one DDS-driven downconversion frequency at a time per channel) -- like ``axis_readout_v2`` and unlike the PFB-based readouts, they do not channelize multiple simultaneous tones. -.. figure:: images/firmware/dyn_readout-blocks.svg +.. figure:: /images/firmware/dyn_readout-blocks.svg :align: center :width: 80% @@ -64,7 +64,7 @@ readouts, they do not channelize multiple simultaneous tones. IP's own). The ADC stream is down-converted once and fans out to both outputs: straight to ``M0_AXIS`` for the pre-decimation view, and through ``fir_decim8_dynro`` to ``M1_AXIS`` for the decimated stream - that feeds :doc:`/avg_buffer`. ``fifo_sync`` carries the tProc-pushed + that feeds :doc:`avg_buffer`. ``fifo_sync`` carries the tProc-pushed config descriptor (freq/phase/mode) into ``down_conversion_dynro``. -------------------------------------------------------------------- @@ -248,7 +248,7 @@ describing the 88-bit ``s0_axis_tdata``/FIFO word layout: This is the same freq/phase/nsamp/outsel/mode field set as ``axis_readout_v2``'s register-composed descriptor (see -:doc:`/readout_v2`'s 83-bit FIFO word), plus one extra field, ``phrst``, that +:doc:`readout_v2`'s 83-bit FIFO word), plus one extra field, ``phrst``, that ``axis_readout_v2`` does not have -- and it arrives as a single AXI-Stream push from the tProcessor rather than being assembled from five separate PYNQ registers and committed with a ``WE_REG`` pulse. @@ -321,7 +321,7 @@ correction): 4. Why There's No Register Map -------------------------------------------------------------------- -Unlike ``axis_readout_v2`` (:doc:`/readout_v2`), neither ``axis_readout_v3`` +Unlike ``axis_readout_v2`` (:doc:`readout_v2`), neither ``axis_readout_v3`` nor ``axis_dyn_readout_v1`` has an AXI-Lite slave port in its top-level Verilog -- there is no ``FREQ_REG``/``PHASE_REG``/``NSAMP_REG``/ ``OUTSEL_REG``/``MODE_REG``/``WE_REG`` set to document, and no register map @@ -349,7 +349,7 @@ section to write for this page. The blocks' only I/O is AXI-Stream: - master - 32 bits - Decimated complex (I, Q) output, 1 sample/clock, to - :doc:`/avg_buffer`. + :doc:`avg_buffer`. .. list-table:: axis_dyn_readout_v1 top-level ports :header-rows: 1 @@ -375,7 +375,7 @@ section to write for this page. The blocks' only I/O is AXI-Stream: - master - 32 bits - Decimated complex (I, Q) output, 1 sample/clock, to - :doc:`/avg_buffer`. + :doc:`avg_buffer`. Because there is no register interface, there is also no PYNQ overlay driver in the usual sense -- see :ref:`readout-dyn-python`. @@ -469,7 +469,7 @@ On tProc v2 (``qick.asm_v2.QickProgramV2``), the program builds one the instructions (``ConfigReadout``) that push that pre-computed word to the readout's ``tproc_ctrl`` port at time ``t``, using the same ``WPORT_WR`` wave-memory-write mechanism used to schedule signal-generator - pulses (see :doc:`/sg_v6`'s tProc-sequencing section). This is the + pulses (see :doc:`../generators/sg_v6`'s tProc-sequencing section). This is the run-time source of the ``s0_axis`` descriptor word described in :ref:`readout-dyn-descriptor`. @@ -499,13 +499,13 @@ by the same firmware control FSM. Related Documentation ---------------------- -* :doc:`/readout` -- readout system overview. -* :doc:`/readout_v2` -- the static, PYNQ-register-configured readout these +* :doc:`index` -- readout system overview. +* :doc:`readout_v2` -- the static, PYNQ-register-configured readout these blocks are the dynamic counterpart of. -* :doc:`/avg_buffer` -- the buffer downstream of ``m_axis``/``m1_axis``. +* :doc:`avg_buffer` -- the buffer downstream of ``m_axis``/``m1_axis``. * :doc:`/tprocv2_trm` -- tProcessor instruction reference, including ``WPORT_WR`` and the timing model used by ``send_readoutconfig()``. -* :doc:`/sg_v6` -- the signal-generator counterpart of tProc-scheduled, +* :doc:`../generators/sg_v6` -- the signal-generator counterpart of tProc-scheduled, ``WPORT_WR``-driven configuration. -* :doc:`topics/freq_matching` -- keeping generator and readout frequencies in +* :doc:`/topics/freq_matching` -- keeping generator and readout frequencies in sync. diff --git a/docs/source/readout_pfb.rst b/docs/source/firmware/readouts/readout_pfb.rst similarity index 95% rename from docs/source/readout_pfb.rst rename to docs/source/firmware/readouts/readout_pfb.rst index 53524fac1..6df89d79e 100644 --- a/docs/source/readout_pfb.rst +++ b/docs/source/firmware/readouts/readout_pfb.rst @@ -8,7 +8,7 @@ PFB Readouts (axis_pfb_readout_v2 / v3 / v4) - QICK Firmware **axis_pfb_readout_v2**, **axis_pfb_readout_v3**, and **axis_pfb_readout_v4** are QICK's polyphase-filter-bank (PFB) readouts: unlike every other readout -documented so far (:doc:`/readout_v2`, :doc:`/readout_dynamic`), a PFB readout +documented so far (:doc:`readout_v2`, :doc:`readout_dynamic`), a PFB readout channelizes its ADC input into many fixed-frequency slices of the band *in hardware*, then lets software/tProc pick which slice(s) to route to its output port(s) and fine-tune each with its own DDS. One PFB readout instance @@ -27,7 +27,7 @@ and its ``AxisPFBReadoutV2``/``V3``/``V4`` subclasses. ZCU216 "tpv2_std" board design (``firmware/Top/216/tpv2_std/bd_2023-1.tcl``, tracked on branch ``feature/114-integrate-hog-fusesoc``, since it predates this branch's docs-only history) instantiates one **axis_pfb_readout_v4** - alongside two ``axis_dyn_readout_v1`` (:doc:`/readout_dynamic`) -- see + alongside two ``axis_dyn_readout_v1`` (:doc:`readout_dynamic`) -- see :ref:`readout-pfb-zcu216` below. .. _readout-pfb-general: @@ -52,7 +52,7 @@ All three versions share the same overall pipeline: 3. **Output routing/selection** -- a subset of the N PFB channels (up to NOUT of them) is routed to the block's NOUT physical AXI-Stream output ports, which is what actually gets built (see :ref:`readout-pfb-zcu216`) - -- each output port typically feeds its own :doc:`/avg_buffer` instance + -- each output port typically feeds its own :doc:`avg_buffer` instance downstream, one PFB readout thus driving multiple avg_buffers. Where the three versions differ is **N** (PFB channel count), **NOUT** @@ -123,7 +123,7 @@ not inferred from naming. ``OUTSEL_REG`` across all 8 channels) picks between the demodulated product, the raw (delay-matched) PFB channel input, or the raw DDS tone -- the same product/input/dds encoding pattern used by the single-tone - readouts (:doc:`/readout_v2`). + readouts (:doc:`readout_v2`). 3. **pfb_mux** (``pfb_mux.sv``) -- a pure combinational 8-to-1 mux, replicated 4 times (one per output). Each output's 3-bit ``CH[0-3]SEL_REG`` selects which of the 8 already-DDS-mixed channels appears on that output @@ -135,7 +135,7 @@ computed once, shared if two outputs pick the same channel -- there is no way to independently re-tune the same PFB channel differently on two outputs simultaneously. -.. figure:: images/firmware/readout_pfb_v2-blocks.svg +.. figure:: /images/firmware/readout_pfb_v2-blocks.svg :align: center :width: 85% @@ -208,7 +208,7 @@ v3 has **no ``OUTSEL_REG``**/output-mode-selection mux at all (confirmed: driver sets ``HAS_OUTSEL = False`` for ``AxisPFBReadoutV3``) -- each output always carries the demodulated product, nothing else. -.. figure:: images/firmware/readout_pfb_v3-blocks.svg +.. figure:: /images/firmware/readout_pfb_v3-blocks.svg :align: center :width: 85% @@ -329,7 +329,7 @@ all three versions have in common: weird value like -0.48, even though this makes no sense"*, i.e. an empirically-determined constant, not one derived from a specific rounding operation in RTL (unlike, say, ``axis_dyn_readout_v1``'s offset -- see - :doc:`/readout_dynamic`). + :doc:`readout_dynamic`). * ``_init_config()`` derives ``DOWNSAMPLING = NCH // 2`` (the PFB's 50%-overlap decimation) and ``CH_OFFSET = NCH // 2`` (the index of the PFB channel centered at DC), and publishes ``pfb_nch``, ``pfb_nout``, @@ -405,7 +405,7 @@ unchanged; only ``NOUT`` differs. Normal QICK programs never call ``set_ch``/``set_freq_int`` directly -- :meth:`.QickProgram.declare_readout` picks the PFB channel/output assignment and frequency for you (via ``QickConfig.calc_ro_regs()``), exactly as -described in :doc:`/readout`'s Python Interface section for the single-tone +described in :doc:`index`'s Python Interface section for the single-tone readouts. .. _readout-pfb-zcu216: @@ -417,8 +417,8 @@ readouts. The flagship ZCU216 board design (``firmware/Top/216/tpv2_std/bd_2023-1.tcl``, tracked on branch ``feature/114-integrate-hog-fusesoc``) instantiates **one** ``axis_pfb_readout_v4_0`` (VLNV ``QICK:QICK:axis_pfb_readout_v4:1.0``) -alongside **two** ``axis_dyn_readout_v1`` instances (:doc:`/readout_dynamic`) -and **ten** ``axis_avg_buffer`` instances (:doc:`/avg_buffer`) -- tracing the +alongside **two** ``axis_dyn_readout_v1`` instances (:doc:`readout_dynamic`) +and **ten** ``axis_avg_buffer`` instances (:doc:`avg_buffer`) -- tracing the block-diagram connections (``connect_bd_intf_net``) confirms exactly how that 10 breaks down, rather than assuming it's all attributable to one core: @@ -458,17 +458,17 @@ AXI-Lite page-granularity convention used elsewhere in this address map Related Documentation -------------------------------------------------------------------- -* :doc:`/readout` -- readout system overview; note its own single-tone - framing applies to :doc:`/readout_v2` and :doc:`/readout_dynamic`, not to +* :doc:`index` -- readout system overview; note its own single-tone + framing applies to :doc:`readout_v2` and :doc:`readout_dynamic`, not to the PFB family described here. -* :doc:`/readout_v2` -- the single-tone, PYNQ-register-configured readout +* :doc:`readout_v2` -- the single-tone, PYNQ-register-configured readout the PFB readouts are architecturally different from (one tunable demodulator vs. a fixed multi-channel bank). -* :doc:`/readout_dynamic` -- the tProc-configured single-tone readouts +* :doc:`readout_dynamic` -- the tProc-configured single-tone readouts (``axis_readout_v3``/``axis_dyn_readout_v1``) that share the ZCU216 board design with ``axis_pfb_readout_v4`` (see :ref:`readout-pfb-zcu216`). -* :doc:`/avg_buffer` -- the buffer IP downstream of each PFB output; a PFB +* :doc:`avg_buffer` -- the buffer IP downstream of each PFB output; a PFB readout with NOUT outputs typically drives NOUT separate avg_buffer instances, as shown on the ZCU216. -* :doc:`topics/freq_matching` -- keeping generator and readout frequencies +* :doc:`/topics/freq_matching` -- keeping generator and readout frequencies in sync. diff --git a/docs/source/readout_v2.rst b/docs/source/firmware/readouts/readout_v2.rst similarity index 90% rename from docs/source/readout_v2.rst rename to docs/source/firmware/readouts/readout_v2.rst index 49dce4923..194a4ac90 100644 --- a/docs/source/readout_v2.rst +++ b/docs/source/firmware/readouts/readout_v2.rst @@ -7,7 +7,7 @@ Readout v2 (axis_readout_v2) - QICK Firmware :depth: 2 **axis_readout_v2** is the digital down-converter (DDC) IP that sits between -the RFDC's ADC output and :doc:`/avg_buffer`. It is the readout used on +the RFDC's ADC output and :doc:`avg_buffer`. It is the readout used on tProc-v1-style single-tone (non-multiplexed, non-PFB) readout channels. The module lives under ``firmware/ip/axis_readout_v2/`` and is exposed to Python through ``qick.drivers.readout.AxisReadoutV2``. @@ -19,7 +19,7 @@ through ``qick.drivers.readout.AxisReadoutV2``. ``axis_readout_v2`` mixes the ADC's real-valued input samples down to baseband with an on-chip DDS, then applies an FIR anti-aliasing filter and decimates by 8 before handing the complex (I, Q) stream to -:doc:`/avg_buffer`. Unlike the newer PFB-based readouts, it demodulates a +:doc:`avg_buffer`. Unlike the newer PFB-based readouts, it demodulates a single, software-tunable frequency (no simultaneous multi-tone channelizer). The datapath, in order: @@ -32,7 +32,7 @@ The datapath, in order: decimation by 8. 3. Output to ``axis_avg_buffer``'s ``s_axis``. -.. figure:: images/firmware/readout_v2-blocks.svg +.. figure:: /images/firmware/readout_v2-blocks.svg :align: center :width: 85% @@ -146,16 +146,16 @@ I/Q before the output mux -- this is the "product" ``outsel`` value. - none - This readout is PYNQ/software-configured only; it has no ``tproc_ctrl`` connection (unlike the dynamic readouts, see - :doc:`/readout_dynamic`). + :doc:`readout_dynamic`). -------------------------------------------------------------------- 5. Python Interface -------------------------------------------------------------------- -As with the buffer (:doc:`/avg_buffer`), normal programs configure this +As with the buffer (:doc:`avg_buffer`), normal programs configure this readout via :meth:`.QickProgram.declare_readout` (``freq``, ``phase``, ``sel``, ``gen_ch``), not by writing registers directly -- see -:doc:`/readout`'s Python Interface section for the full +:doc:`index`'s Python Interface section for the full ``declare_readout()``/``trigger()``/``acquire()`` workflow. ``AxisReadoutV2.set_all()``/``set_all_int()`` exist for direct register access but are explicitly for debugging: *"Normally the [readout] is @@ -164,10 +164,10 @@ configured based on parameters supplied in QickProgram.declare_readout()."* Related Documentation ---------------------- -* :doc:`/readout` -- readout system overview and the normal +* :doc:`index` -- readout system overview and the normal ``declare_readout()`` workflow. -* :doc:`/avg_buffer` -- the buffer downstream of this readout's output. -* :doc:`/readout_dynamic` -- the tProc-configured readouts +* :doc:`avg_buffer` -- the buffer downstream of this readout's output. +* :doc:`readout_dynamic` -- the tProc-configured readouts (``axis_readout_v3``/``axis_dyn_readout_v1``), for comparison. -* :doc:`topics/freq_matching` -- keeping generator and readout frequencies +* :doc:`/topics/freq_matching` -- keeping generator and readout frequencies in sync. diff --git a/docs/source/support_cores.rst b/docs/source/firmware/support_cores.rst similarity index 96% rename from docs/source/support_cores.rst rename to docs/source/firmware/support_cores.rst index 0a308a7ce..c5688b326 100644 --- a/docs/source/support_cores.rst +++ b/docs/source/firmware/support_cores.rst @@ -10,10 +10,10 @@ The three cores on this page -- **axis_constant_iq**, **axis_set_reg**, and **axis_streamer** -- are small, single-purpose utility blocks that live under ``firmware/ip/`` alongside the readout and signal-generator families but don't belong to either one. Each is 1-7 RTL files, so rather than a -full page per core (as :doc:`/readout_v2`, :doc:`/sg_v6`, etc. get), they +full page per core (as :doc:`readouts/readout_v2`, :doc:`generators/sg_v6`, etc. get), they share this one page, one section each. -.. figure:: images/firmware/support_cores-blocks.svg +.. figure:: /images/firmware/support_cores-blocks.svg :align: center :width: 85% @@ -43,9 +43,9 @@ phase that gets mixed up to that frequency. This is a deliberate contrast with the two arbitrary/multiplexed generator families already documented: -* :doc:`/sg_v6` synthesizes a shaped, arbitrary envelope from a DDS + BRAM +* :doc:`generators/sg_v6` synthesizes a shaped, arbitrary envelope from a DDS + BRAM waveform engine, sequenced pulse-by-pulse by tProc-issued descriptors. -* :doc:`/sg_mux8` has no envelope memory either, but does have its own +* :doc:`generators/sg_mux8` has no envelope memory either, but does have its own per-tone DDS (up to 8 simultaneous tones), and is still sequenced by the tProcessor (a streamed mask + duration selects which tones play, when). @@ -427,12 +427,12 @@ appear wired into a shipped QICK board bitstream either. completely different, higher-level, **purely software** abstraction: a background Python ``Thread`` that repeatedly calls ``soc.get_tproc_counter()`` and ``soc.get_accumulated()`` to pull already-accumulated I/Q points out of -the averaging buffer (:doc:`/avg_buffer`) while a tProc program runs, +the averaging buffer (:doc:`readouts/avg_buffer`) while a tProc program runs, queuing the results for the main thread to consume via ``poll_data()``. It never touches an MMIO register map and never references any of ``axis_streamer``'s ``START``/``FLUSH``/``MODE``/``NSAMP``/``LOST``/ ``STATUS`` registers -- its "streaming" is a software polling loop layered -on top of :doc:`/avg_buffer` and the tProcessor's shot counter, with no +on top of :doc:`readouts/avg_buffer` and the tProcessor's shot counter, with no dependency on the ``axis_streamer`` IP block at all. So: as verified in this codebase, ``axis_streamer`` currently has no @@ -447,13 +447,13 @@ drivers. Related Documentation ---------------------- -* :doc:`/sg_v6` -- arbitrary-envelope signal generator; contrast with +* :doc:`generators/sg_v6` -- arbitrary-envelope signal generator; contrast with ``axis_constant_iq``'s lack of any DDS or envelope memory. -* :doc:`/sg_mux8` -- fixed-tone multiplexed generator; also contrasted with +* :doc:`generators/sg_mux8` -- fixed-tone multiplexed generator; also contrasted with ``axis_constant_iq`` above. -* :doc:`/avg_buffer` -- the buffer that :class:`.DataStreamer` actually +* :doc:`readouts/avg_buffer` -- the buffer that :class:`.DataStreamer` actually polls, as opposed to ``axis_streamer``. -* :doc:`/readout_dynamic` -- another block whose Python-side object is +* :doc:`readouts/readout_dynamic` -- another block whose Python-side object is constructed manually rather than through the normal PYNQ overlay-scan mechanism, for comparison with ``axis_set_reg``'s pure metadata-tracing role. diff --git a/docs/source/index.rst b/docs/source/index.rst index ce3e1dde1..2c30e8591 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -79,58 +79,30 @@ specific core's page or the assembly-level tProcessor reference. :maxdepth: 2 :caption: 5. Firmware Overview - firmware + firmware/index The **readout system** turns ADC samples into the I/Q data your program gets back. QICK offers several down-converter and buffer cores with different tradeoffs (software- vs. tProc-configured, on-chip BRAM vs. DDR4 capture, plus a resonator simulator for hardware-in-the-loop testing) -- start at -:doc:`readout` for the concepts and the normal ``declare_readout()``/ +:doc:`firmware/readouts/index` for the concepts and the normal ``declare_readout()``/ ``acquire()`` workflow, then dip into a specific core's page for register- level detail. -.. toctree:: - :maxdepth: 2 - :caption: 6. Readout System - - readout - readout_v2 - readout_dynamic - readout_pfb - avg_buffer - mr_buffer_et - kidsim - The **signal generators** turn your program's pulse definitions into DAC output. QICK offers both single-tone arbitrary-envelope generators (for shaped pulses) and multiplexed fixed-tone generators (for playing several -simultaneous tones from one channel) -- start at :doc:`generators` for an -overview of which core fits which experiment, then see :doc:`sg_v6` for the +simultaneous tones from one channel) -- start at :doc:`firmware/generators/index` for an +overview of which core fits which experiment, then see :doc:`firmware/generators/sg_v6` for the full worked Python examples shared across the family. -.. toctree:: - :maxdepth: 2 - :caption: 7. Signal Generators - - generators - sg_v6 - sg_mux8 - sg_mixmux8 - sg_int4_v2 - sg_v4 The **support & utility cores** are smaller IP blocks -- a constant-IQ tone source, a tProc-output register/trigger helper, and an AXI-Stream buffering core -- that don't fit into either the readout or signal-generator families -above; see :doc:`support_cores` for what each one does and how (or whether) +above; see :doc:`firmware/support_cores` for what each one does and how (or whether) it's exposed to Python. -.. toctree:: - :maxdepth: 2 - :caption: 8. Support & Utility Cores - - support_cores - .. toctree:: :maxdepth: 2 :caption: 9. Python API Reference @@ -179,12 +151,12 @@ Learning Path Recommendations 1. Read the :doc:`quick_start` guide to set up your board 2. Complete the **Basic Tutorials** (00-05) to understand core concepts 3. Work through **Intermediate Tutorials** (06-09) for practical measurements -4. Read :doc:`firmware` for the big picture, then explore **Advanced +4. Read :doc:`firmware/index` for the big picture, then explore **Advanced Tutorials** (10-14) for specialized applications **Already familiar with QICK?** Jump directly to: -- :doc:`readout` and :doc:`generators` for the readout/generator hardware +- :doc:`firmware/readouts/index` and :doc:`firmware/generators/index` for the readout/generator hardware reference, organized by which core is on your channel - :doc:`modules` for full API documentation - :doc:`topics/index` for deep dives on specific topics diff --git a/docs/source/modules.rst b/docs/source/modules.rst index ba2dd52c1..4e4cfb78d 100644 --- a/docs/source/modules.rst +++ b/docs/source/modules.rst @@ -4,7 +4,7 @@ Software API This page is the raw, auto-generated API reference -- every public class, method, and function in ``qick_lib``, with its docstring. For most tasks you don't need to browse it directly: the narrative pages -(:doc:`/generators`, :doc:`/readout`, :doc:`/tprocv2_trm`, ...) already +(:doc:`/firmware/generators/index`, :doc:`/firmware/readouts/index`, :doc:`/tprocv2_trm`, ...) already link to the specific method you need via cross-references. Come here when you need the full signature/parameter list for something, or want to see everything a class exposes at a glance. @@ -44,7 +44,7 @@ Connecting to the board :class:`.QickSoc` (:mod:`qick.qick`) is the main entry point -- instantiate it once, then reach every generator/readout/buffer/tProc driver through its ``soc.gens``/``soc.readouts``/``soc.avg_bufs``/``soc.tproc`` arrays (see -:doc:`/firmware` for what's on your board). :mod:`qick.rfboard` extends it +:doc:`/firmware/index` for what's on your board). :mod:`qick.rfboard` extends it for boards with an external RF front-end. :mod:`qick.pyro` lets you connect to a board running headless over the network instead of locally. @@ -53,7 +53,7 @@ Hardware drivers You'll interact with these through the ``soc.gens``/``soc.readouts``/ ``soc.avg_bufs``/``soc.tproc`` arrays above, not by importing these -modules directly -- see :doc:`/generators`, :doc:`/readout`, and +modules directly -- see :doc:`/firmware/generators/index`, :doc:`/firmware/readouts/index`, and :doc:`/tprocv1`/:doc:`/tprocv2_trm` for the driver classes' individual pages (register maps, RTL cross-references) rather than the bare docstrings here. @@ -71,7 +71,7 @@ Assembly and compilation internals Normal programs don't call these directly -- :mod:`qick.asm_v2`/ :mod:`qick.asm_v1` invoke them for you. Useful if you're debugging a compiled program or working with raw assembly text (see -:doc:`topics/asmv2_cheatsheet`). +:doc:`/topics/asmv2_cheatsheet`). .. autosummary:: :toctree: _autosummary @@ -92,7 +92,7 @@ Utilities and framework internals :mod:`qick.helpers` holds small standalone support functions. :mod:`qick.streamer` is :class:`.DataStreamer`, a polling thread for continuous acquisition -- not a driver for a specific IP core (see -:doc:`/support_cores` if you were looking for the ``axis_streamer`` RTL +:doc:`/firmware/support_cores` if you were looking for the ``axis_streamer`` RTL block instead, a different thing despite the name). :mod:`qick.ip` has the base :class:`.SocIP`/:class:`.QickIP` driver classes and the board metadata tracing every driver's ``configure_connections()`` uses -- framework diff --git a/docs/source/topics/asmv2_cheatsheet.rst b/docs/source/topics/asmv2_cheatsheet.rst index 8d820705a..21500621a 100644 --- a/docs/source/topics/asmv2_cheatsheet.rst +++ b/docs/source/topics/asmv2_cheatsheet.rst @@ -259,6 +259,6 @@ Related Documentation --------------------- * :doc:`/tprocv2_trm` - Complete tProcessor v2 reference manual -* :doc:`/firmware` - Firmware overview and channel assignments -* :doc:`/sg_v6` - Signal Generator v6 documentation -* :doc:`/readout` - Readout system documentation +* :doc:`/firmware/index` - Firmware overview and channel assignments +* :doc:`/firmware/generators/sg_v6` - Signal Generator v6 documentation +* :doc:`/firmware/readouts/index` - Readout system documentation diff --git a/docs/source/topics/freq_matching.rst b/docs/source/topics/freq_matching.rst index 6308f2531..9cb4b9bd9 100644 --- a/docs/source/topics/freq_matching.rst +++ b/docs/source/topics/freq_matching.rst @@ -73,7 +73,7 @@ Best Practices Related Documentation --------------------- -* :doc:`/sg_v6` - Signal Generator v6 -* :doc:`/readout` - Readout system -* :doc:`/firmware` - Clock domains and sample rates +* :doc:`/firmware/generators/sg_v6` - Signal Generator v6 +* :doc:`/firmware/readouts/index` - Readout system +* :doc:`/firmware/index` - Clock domains and sample rates * :doc:`changing_fs` - Custom sample rates diff --git a/docs/source/topics/playing_pulses.rst b/docs/source/topics/playing_pulses.rst index ae93de753..1d6955093 100644 --- a/docs/source/topics/playing_pulses.rst +++ b/docs/source/topics/playing_pulses.rst @@ -13,7 +13,7 @@ How to play pulses with QICK ``qick.asm_v2`` in the same session that found the problem. With the tProcessor v2 and Signal Generator v6 (or any of QICK's other -generator cores -- see :doc:`/generators`), playing a pulse involves three +generator cores -- see :doc:`/firmware/generators/index`), playing a pulse involves three steps, all done through a :class:`.QickProgram` subclass: .. contents:: @@ -37,7 +37,7 @@ Step 1: Loading a waveform envelope Each generator with envelope memory (SG-v6, SG-v4, SG-int4-v2 -- not the multiplexed SG-Mux8/SG-MixMux8 cores, which play fixed tones instead; see -:doc:`/generators`) stores I/Q envelope data internally. Multiple envelopes +:doc:`/firmware/generators/index`) stores I/Q envelope data internally. Multiple envelopes can be stored per generator, and one envelope can be reused across several pulses (e.g. a Gaussian shape reused for pulses at different frequencies). @@ -120,7 +120,7 @@ play at a given time, relative to the current shot: **Triggering a readout at the same time as a pulse** -- pass both to the same or a separate :meth:`.QickProgramV2.trigger` call at the matching time -(see :doc:`/readout`'s Python Interface section for the full +(see :doc:`/firmware/readouts/index`'s Python Interface section for the full ``declare_readout``/``trigger``/``acquire`` workflow): .. code-block:: python @@ -141,8 +141,8 @@ Related Documentation --------------------- * :doc:`/tprocv2_trm` - tProcessor v2 instruction set and register-level detail -* :doc:`/generators` - Which generator cores support envelopes vs. fixed tones -* :doc:`/sg_v6` - Signal Generator v6 documentation, with more worked examples -* :doc:`/readout` - Declaring and triggering a readout alongside a pulse -* :doc:`/firmware` - Channel assignments and firmware overview -* :doc:`../tutorials/index` - tProc v2 tutorial examples +* :doc:`/firmware/generators/index` - Which generator cores support envelopes vs. fixed tones +* :doc:`/firmware/generators/sg_v6` - Signal Generator v6 documentation, with more worked examples +* :doc:`/firmware/readouts/index` - Declaring and triggering a readout alongside a pulse +* :doc:`/firmware/index` - Channel assignments and firmware overview +* :doc:`/tutorials/index` - tProc v2 tutorial examples diff --git a/docs/source/topics/readout_modes.rst b/docs/source/topics/readout_modes.rst index c3792bcf0..6afdf6124 100644 --- a/docs/source/topics/readout_modes.rst +++ b/docs/source/topics/readout_modes.rst @@ -40,7 +40,7 @@ Decimated (``acquire_decimated``) The decimating readout streams out the *time-domain* I/Q waveform of the readout window itself (after the readout's own decimation stage, not the raw ADC rate -- -see :doc:`/firmware` for the DDC/decimation chain), instead of a single integrated +see :doc:`/firmware/index` for the DDC/decimation chain), instead of a single integrated point. * Use this to look at the readout waveform directly: verifying that your readout @@ -91,6 +91,6 @@ interleave other work between rounds. See also -------- -* :doc:`/readout` -- the readout hardware itself (DDC, decimation, buffers). +* :doc:`/firmware/readouts/index` -- the readout hardware itself (DDC, decimation, buffers). * :doc:`timing` -- how readout windows relate to the tProc's timed queues. * :doc:`freq_matching` -- keeping generator and readout frequencies in sync. diff --git a/docs/source/topics/timing.rst b/docs/source/topics/timing.rst index 03766d8cb..04e8b0ad4 100644 --- a/docs/source/topics/timing.rst +++ b/docs/source/topics/timing.rst @@ -198,5 +198,5 @@ Related Documentation --------------------- * :doc:`/tprocv2_trm` - Complete tProcessor v2 reference manual -* :doc:`/firmware` - Firmware overview and clock frequencies +* :doc:`/firmware/index` - Firmware overview and clock frequencies * :doc:`../tprocv2_trm` - Time management section in main manual diff --git a/docs/source/topics/units.rst b/docs/source/topics/units.rst index 8e8dbfb5e..c940f7491 100644 --- a/docs/source/topics/units.rst +++ b/docs/source/topics/units.rst @@ -62,5 +62,5 @@ Related Documentation --------------------- * :doc:`/tprocv2_trm` - tProcessor timing model -* :doc:`/sg_v6` - Signal Generator v6 documentation -* :doc:`/readout` - Readout system documentation +* :doc:`/firmware/generators/sg_v6` - Signal Generator v6 documentation +* :doc:`/firmware/readouts/index` - Readout system documentation diff --git a/docs/source/tprocv1.rst b/docs/source/tprocv1.rst index f6c4277cf..64d38b2e4 100644 --- a/docs/source/tprocv1.rst +++ b/docs/source/tprocv1.rst @@ -628,9 +628,9 @@ Related Documentation * :doc:`/tprocv2_trm` -- the current tProcessor (v2), recommended for new designs. -* :doc:`/firmware` -- system-level firmware overview (signal generators, +* :doc:`/firmware/index` -- system-level firmware overview (signal generators, readout, channel assignments). -* :doc:`/avg_buffer` -- Averager + Buffer readout block, whose ``trigger`` +* :doc:`/firmware/readouts/avg_buffer` -- Averager + Buffer readout block, whose ``trigger`` input is typically driven from a v1 tProc output channel bit. * `tProcessor_64_and_Signal_Generator_V4.pdf `_ diff --git a/docs/source/tprocv2_trm.rst b/docs/source/tprocv2_trm.rst index e2f5b859a..679a4059d 100644 --- a/docs/source/tprocv2_trm.rst +++ b/docs/source/tprocv2_trm.rst @@ -15,7 +15,7 @@ QICK tProcessor v2 - Complete Reference Manual .. note:: This is the complete reference manual for the qick_processor (tProcV2). For system-level firmware overview (signal generators, readout, channel assignments), - see :doc:`/firmware`. If you are working with older, legacy tProc v1 + see :doc:`/firmware/index`. If you are working with older, legacy tProc v1 hardware (``axis_tproc64x32_x8``) instead, see :doc:`/tprocv1`. This document was updated to match the current RTL (``firmware/rtl_lib/``). @@ -5290,7 +5290,7 @@ For complete API documentation, see Chapter 12. driver, and ``Waveform`` actually lives in ``qick.asm_v2``, not ``qick.qick_asm``. The examples below use the real, current :class:`.QickProgram`-based workflow (the same one used throughout - :doc:`/sg_v6`, :doc:`/readout`, and :doc:`/generators`), verified against + :doc:`/firmware/generators/sg_v6`, :doc:`/firmware/readouts/index`, and :doc:`/firmware/generators/index`), verified against ``qick.asm_v2``/``qick.qick_asm``/``qick.drivers.tproc`` in this session. Raw assembly is still shown where it's genuinely the right tool -- true hardware-timed conditional branching (:ref:`tproc-conditional-feedback`) @@ -5333,7 +5333,7 @@ reps/rounds for you. --------------------------------------------------- This example sends a pulse and captures its raw (decimated) waveform on a -readout channel -- see :doc:`topics/readout_modes` for accumulated +readout channel -- see :doc:`/topics/readout_modes` for accumulated (``acquire()``) vs. decimated (``acquire_decimated()``) readout. .. code-block:: python @@ -5371,7 +5371,7 @@ you write it with high-level Python calls, not hand-assembled instructions: :meth:`.QickProgramV2.read_and_jump` combines a readout-register read with a conditional jump, and :meth:`.QickProgramV2.label` marks the jump target. This condensed example is adapted from the full working version in -:doc:`tutorials/04_Real_Time_Feedback`. +:doc:`/tutorials/04_Real_Time_Feedback`. .. code-block:: python @@ -5486,12 +5486,12 @@ This example combines everything: DAC pulse, ADC capture, and data analysis. ------------------------------------------ The Signal Generator v6 (SG-v6) is one of several waveform generation -cores QICK supports for DAC outputs -- see :doc:`/generators` for the full -family and :doc:`/firmware` for how many channels of which type your +cores QICK supports for DAC outputs -- see :doc:`/firmware/generators/index` for the full +family and :doc:`/firmware/index` for how many channels of which type your specific board has (it varies by board, see :ref:`std-firmware-per-board`). For complete documentation and worked Python examples (basic pulse, shaped -envelope, queued pulses), see :doc:`/sg_v6`'s "Python Usage" section -- +envelope, queued pulses), see :doc:`/firmware/generators/sg_v6`'s "Python Usage" section -- they use the same :meth:`.QickProgram.declare_gen`/ :meth:`.QickProgram.add_pulse`/:meth:`.QickProgram.pulse` pattern as every other example in this chapter. @@ -5501,15 +5501,15 @@ other example in this chapter. The readout system captures ADC data, triggered by a dedicated single-bit ``trig_N_o`` pin per buffer instance (see :ref:`tproc-ports` in -:doc:`/firmware` for the full pin model -- it is *not* a bit within a +:doc:`/firmware/index` for the full pin model -- it is *not* a bit within a channel-numbered data word). QICK supports several readout variants -(single-tone, tProc-configured, and channelized/PFB) -- see :doc:`/readout` +(single-tone, tProc-configured, and channelized/PFB) -- see :doc:`/firmware/readouts/index` for the family overview and :ref:`std-firmware-per-board` for which variant(s) your board uses. For the normal workflow (:meth:`.QickProgram.declare_readout`, :meth:`.QickProgramV2.trigger`, :meth:`.AcquireMixin.acquire`/ -:meth:`.AcquireMixin.acquire_decimated`), see :doc:`/readout`'s "Python +:meth:`.AcquireMixin.acquire_decimated`), see :doc:`/firmware/readouts/index`'s "Python Interface" section, or the worked examples earlier in this chapter (all of which declare and trigger a readout channel the same way). @@ -5575,9 +5575,9 @@ tProc/firmware timing, unaffected by PS-side overhead: 13.10. Repository of Examples ----------------------------- -This documentation's own tutorial notebooks (:doc:`tutorials/index`) are +This documentation's own tutorial notebooks (:doc:`/tutorials/index`) are the primary worked-example resource, all runnable on real hardware (or, for -tutorials 00-07, on the :doc:`tutorials/index`'s Colab-runnable emulator +tutorials 00-07, on the :doc:`/tutorials/index`'s Colab-runnable emulator port): .. list-table:: Tutorial Notebooks Covering This Chapter's Topics @@ -5586,13 +5586,13 @@ port): * - Notebook - Covers - * - :doc:`tutorials/01_Basic_Sequencing` + * - :doc:`/tutorials/01_Basic_Sequencing` - Basic pulses, sequences, acquisition (§13.1-13.2) - * - :doc:`tutorials/04_Real_Time_Feedback` + * - :doc:`/tutorials/04_Real_Time_Feedback` - Conditional pulses, active reset, thresholding (§13.3) - * - :doc:`tutorials/02_Parameter_Sweeps` + * - :doc:`/tutorials/02_Parameter_Sweeps` - 1D/2D sweeps with ``QickSweep1D``/``add_loop`` (§13.4) - * - :doc:`tutorials/06_Generators_And_Readouts` + * - :doc:`/tutorials/06_Generators_And_Readouts` - Generators, readouts, I/Q mixing (§13.5-13.7) 13.11. Where to Find More Examples @@ -5601,7 +5601,7 @@ port): For more elaborate examples (multi-qubit experiments, advanced feedback loops, calibration routines), refer to: -- **Tutorial series** (:doc:`tutorials/index`) – The full 00-14 series, +- **Tutorial series** (:doc:`/tutorials/index`) – The full 00-14 series, from basic sequencing through streaming/DSP, custom firmware integration, and XCOM multi-board network synchronization. - **Official QICK Demos Repository** – diff --git a/docs/source/tutorials/15_QICKBox_RF_Daughtercards.ipynb b/docs/source/tutorials/15_QICKBox_RF_Daughtercards.ipynb index 4e66bba0e..80bf75a05 100644 --- a/docs/source/tutorials/15_QICKBox_RF_Daughtercards.ipynb +++ b/docs/source/tutorials/15_QICKBox_RF_Daughtercards.ipynb @@ -23,7 +23,7 @@ "\n", "**References:**\n", "- QICK Documentation: https://docs.qick.dev\n", - "- Firmware overview: [Firmware Overview](../firmware.rst)\n" + "- Firmware overview: [Firmware Overview](../firmware/index.rst)\n" ] }, { @@ -522,7 +522,7 @@ "- Return to [`07_Advanced_Generators_And_Readouts.ipynb`](./07_Advanced_Generators_And_Readouts.ipynb)\n", " for multiplexed generators/readouts and the PFB readout channelizer, which apply equally to signals\n", " routed through these daughtercards\n", - "- See the [Firmware Overview](../firmware.rst) for how daughtercard ports map to generator/readout\n", + "- See the [Firmware Overview](../firmware/index.rst) for how daughtercard ports map to generator/readout\n", " channels in a given bitstream\n" ] } From abe4c7a3a72c5899a67d4e9a59bbd4f5b98ed38f Mon Sep 17 00:00:00 2001 From: Horacio Arnaldi Date: Thu, 10 Sep 2026 14:04:37 -0500 Subject: [PATCH 18/23] Update the common setup of acquire vs acquire_decimated section --- docs/source/topics/readout_modes.rst | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/source/topics/readout_modes.rst b/docs/source/topics/readout_modes.rst index 6afdf6124..dd3970159 100644 --- a/docs/source/topics/readout_modes.rst +++ b/docs/source/topics/readout_modes.rst @@ -59,12 +59,19 @@ Common setup ------------ Both methods require the acquisition to be described first, via -:meth:`.AcquireMixin.setup_acquire` (which needs the tProc counter address and -the loop dimensions -- see :meth:`.AcquireMixin.setup_counter` for the subset of -that needed if you have no readouts at all, e.g. a pure-generator program you -still want a progress bar for). Both accept the same ``rounds``, ``start_src``, -``remove_offset``, and ``step_rounds`` arguments; ``step_rounds=True`` in either -case hands control of the round-by-round loop to your own code via +:meth:`.AcquireMixin.setup_acquire` (which needs the tProc counter address, the +loop dimensions, and which loop level to average over -- see +:meth:`.AcquireMixin.setup_counter` for the subset of that needed if you have no +readouts at all, e.g. a pure-generator program you still want a progress bar +for). In practice you rarely call this yourself: :class:`.AveragerProgramV2` +(and the tProc v1 averager classes) call it for you in ``__init__``, from +``reps`` and any loops added with ``add_loop()``. You only need +:meth:`.AcquireMixin.setup_acquire` directly if you build a program on the +lower-level :class:`.AcquireProgramV2`/:class:`.AcquireMixin` without going +through :class:`.AveragerProgramV2`. Both ``acquire()``/``acquire_decimated()`` +accept the same ``rounds``, ``start_src``, ``remove_offset``, and +``step_rounds`` arguments; ``step_rounds=True`` in either case hands control of +the round-by-round loop to your own code via ``prepare_round()``/``finish_round()``/``finish_acquire()``, if you need to interleave other work between rounds. From 863c87bac7218b3ae3b13f6bab26cdec78b2dea1 Mon Sep 17 00:00:00 2001 From: Horacio Arnaldi Date: Fri, 11 Sep 2026 10:07:45 -0500 Subject: [PATCH 19/23] Update the index to add the signal generators in place of just the sgv6 --- docs/source/firmware/index.rst | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/docs/source/firmware/index.rst b/docs/source/firmware/index.rst index 637a9d868..28aa2bcc7 100644 --- a/docs/source/firmware/index.rst +++ b/docs/source/firmware/index.rst @@ -18,7 +18,10 @@ System Overview The QICK firmware includes the following components: * **tProcessor v2** - Real-time co-processor for sequencing and feedback -* **Signal Generator v6 (SG-v6)** - DDS-based waveform generators for DAC outputs +* **Signal Generators** - DDS-based waveform generators for DAC outputs; QICK + ships several generator cores (:doc:`generators/sg_v6` being the flagship + arbitrary-envelope one), and a board's standard firmware provisions its own + mix -- see :doc:`generators/index` * **Readout System** - ADC data acquisition with DDC, filtering, and averaging .. list-table:: @@ -60,10 +63,20 @@ Fast-speed buffers were removed to save memory space. Raw data can be captured a the Zynq PS configures everything over AXI (purple) and is the boundary between the PS (software) and PL (FPGA fabric) sides of the chip. -Signal Generator v6 (SG-v6) ---------------------------- +Signal Generators +----------------- + +QICK ships several signal-generator IP cores for the DAC-output stage -- +:doc:`generators/sg_v6` (arbitrary I/Q envelopes, the flagship/default +choice), :doc:`generators/sg_int4_v2` (arbitrary envelope, 4x-interpolated, +lighter-weight), :doc:`generators/sg_mixmux8` and :doc:`generators/sg_mux8` +(fixed multi-tone/CW, up to 8 simultaneous tones per channel), and the legacy +:doc:`generators/sg_v4`. Which one(s) a given board's standard firmware uses, +and how many of each, is a per-board decision -- see +:ref:`std-firmware-per-board`. -Output channels driving DACs use the **Signal Generator v6**, which has the following features: +**Signal Generator v6 (SG-v6)**, the flagship arbitrary-envelope core, has +the following features: * Supports uploading I/Q envelopes * 32-bit resolution for both frequency and phase @@ -71,9 +84,9 @@ Output channels driving DACs use the **Signal Generator v6**, which has the foll * 16 parallel samples per clock cycle (256-bit output bus) * Maximum envelope length: 65536 samples per channel -For complete documentation, see :doc:`generators/sg_v6`. If your board uses a -different generator core (multiplexed, interpolated, or the legacy v4), see -:doc:`generators/index` for the full family and which one fits which experiment. +For the full generator family and which one fits which experiment, see +:doc:`generators/index`. For complete SG-v6 documentation, see +:doc:`generators/sg_v6`. Readout System -------------- From b60bac3d423a452123e3e2ac49265aca1fed208c Mon Sep 17 00:00:00 2001 From: Sho Uemura Date: Fri, 11 Sep 2026 15:01:23 -0500 Subject: [PATCH 20/23] merge tutorial README and index files --- docs/source/firmware/index.rst | 2 +- docs/source/index.rst | 2 +- docs/source/topics/example_code.rst | 2 +- docs/source/topics/playing_pulses.rst | 2 +- docs/source/tprocv2_trm.rst | 6 +- docs/source/tutorials/README.md | 115 ------------- docs/source/tutorials/README.rst | 228 ++++++++++++++++++++++++++ docs/source/tutorials/index.rst | 117 ------------- 8 files changed, 235 insertions(+), 239 deletions(-) delete mode 100644 docs/source/tutorials/README.md create mode 100644 docs/source/tutorials/README.rst delete mode 100644 docs/source/tutorials/index.rst diff --git a/docs/source/firmware/index.rst b/docs/source/firmware/index.rst index 28aa2bcc7..c1263e680 100644 --- a/docs/source/firmware/index.rst +++ b/docs/source/firmware/index.rst @@ -542,5 +542,5 @@ Related Documentation * :doc:`readouts/avg_buffer` - Averaged/raw buffer IP downstream of every readout variant * :doc:`readouts/mr_buffer_et` - Multi-rate buffer (DDR4/streaming) shared readout path * :doc:`/topics/asmv2_cheatsheet` - tProc v2 assembly quick reference -* :doc:`/tutorials/index` - tProc v2 tutorial examples +* :doc:`/tutorials/README` - tProc v2 tutorial examples * `Signal Generator v6 source `_ diff --git a/docs/source/index.rst b/docs/source/index.rst index 2c30e8591..95c7fb42b 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -68,7 +68,7 @@ The documentation is organized as a **progressive learning path** from beginner :maxdepth: 2 :caption: 2. Tutorials - tutorials/index + tutorials/README The **firmware overview** is the map: which boards QICK supports, which cores live on each one, and how the tProcessor, signal generators, and diff --git a/docs/source/topics/example_code.rst b/docs/source/topics/example_code.rst index 76702847f..a728162ad 100644 --- a/docs/source/topics/example_code.rst +++ b/docs/source/topics/example_code.rst @@ -5,7 +5,7 @@ Example code from the community List originally contributed by `Jay Chien `_ (`PR #412 `_). -Beyond the tutorials in :doc:`../tutorials/index`, QICK collaborators have shared +Beyond the tutorials in :doc:`../tutorials/README`, QICK collaborators have shared larger example codebases built on top of QICK. These are useful as reference for structuring real measurement code, but are maintained independently of this repository and are not guaranteed to track the latest QICK release. diff --git a/docs/source/topics/playing_pulses.rst b/docs/source/topics/playing_pulses.rst index 1d6955093..83b441885 100644 --- a/docs/source/topics/playing_pulses.rst +++ b/docs/source/topics/playing_pulses.rst @@ -145,4 +145,4 @@ Related Documentation * :doc:`/firmware/generators/sg_v6` - Signal Generator v6 documentation, with more worked examples * :doc:`/firmware/readouts/index` - Declaring and triggering a readout alongside a pulse * :doc:`/firmware/index` - Channel assignments and firmware overview -* :doc:`/tutorials/index` - tProc v2 tutorial examples +* :doc:`/tutorials/README` - tProc v2 tutorial examples diff --git a/docs/source/tprocv2_trm.rst b/docs/source/tprocv2_trm.rst index 679a4059d..04a60e8b7 100644 --- a/docs/source/tprocv2_trm.rst +++ b/docs/source/tprocv2_trm.rst @@ -5575,9 +5575,9 @@ tProc/firmware timing, unaffected by PS-side overhead: 13.10. Repository of Examples ----------------------------- -This documentation's own tutorial notebooks (:doc:`/tutorials/index`) are +This documentation's own tutorial notebooks (:doc:`/tutorials/README`) are the primary worked-example resource, all runnable on real hardware (or, for -tutorials 00-07, on the :doc:`/tutorials/index`'s Colab-runnable emulator +tutorials 00-07, on the :doc:`/tutorials/README`'s Colab-runnable emulator port): .. list-table:: Tutorial Notebooks Covering This Chapter's Topics @@ -5601,7 +5601,7 @@ port): For more elaborate examples (multi-qubit experiments, advanced feedback loops, calibration routines), refer to: -- **Tutorial series** (:doc:`/tutorials/index`) – The full 00-14 series, +- **Tutorial series** (:doc:`/tutorials/README`) – The full series, from basic sequencing through streaming/DSP, custom firmware integration, and XCOM multi-board network synchronization. - **Official QICK Demos Repository** – diff --git a/docs/source/tutorials/README.md b/docs/source/tutorials/README.md deleted file mode 100644 index 8cdc807f7..000000000 --- a/docs/source/tutorials/README.md +++ /dev/null @@ -1,115 +0,0 @@ -# QICK Tutorial Notebooks - -This directory contains Jupyter notebooks that introduce the QICK framework and the tProc v2. - -## Prerequisites - -- QICK installed on RFSoC board or remote PC -- Firmware bitstream file (`.bit`) for your board -- Jupyter notebook/lab - -## Notebooks - -### Basic (00–05) - -| # | Notebook | Description | -|:-|:---|:---| -| 00 | `00_Getting_Started.ipynb` | Connect to the board, inspect hardware configuration | -| 01 | `01_Basic_Sequencing.ipynb` | Define pulses, create sequences, acquire data | -| 02 | `02_Parameter_Sweeps.ipynb` | 1D and 2D parameter sweeps | -| 03 | `03_Advanced_Timing.ipynb` | `delay` vs `wait`, auto-timing, avoiding collisions | -| 04 | `04_Real_Time_Feedback.ipynb` | Conditional pulses, active reset, thresholding | -| 05 | `05_Dynamic_Parameters_Subroutines.ipynb` | Virtual-Z gates, subroutines, dynamic updates | - -### Intermediate (06–09) - -| # | Notebook | Description | -|:-|:---|:---| -| 06 | `06_Generators_And_Readouts.ipynb` | Basic waveform generators, readout resonators, I/Q mixing | -| 07 | `07_Advanced_Generators_And_Readouts.ipynb` | Muxed generators, PFB readout, dynamic readouts, fast dynamic readout, electrical delay calibration, IQ offsets, performance benchmarks | -| 08 | `08_Hardware_Buffers.ipynb` | DDR4 and MR buffers, data capture | -| 09 | `09_Appendix_Tips_And_Limits.ipynb` | Common errors, limits, debugging tips | - -### Advanced (10–15) - -| # | Notebook | Description | -|:-|:---|:---| -| 10 | `10_Multi_Board_Synchronization.ipynb` | Synchronize multiple boards using external clock and external start signals | -| 11 | `11_Streaming_And_RealTime_Processing.ipynb` | IQ streaming, on-FPGA averaging, real-time decimation | -| 12 | `12_DSP_Blocks_And_Correlators.ipynb` | FIR filters, DDS tuning, hardware correlators | -| 13 | `13_Custom_Firmware_Integration.ipynb` | Adding custom Verilog/VHDL, AXI-lite interface, rebuilding | -| 14 | `14_XCOM_Network_Synchronization.ipynb` | Full mesh network for multi-board synchronization and low-latency communication (requires FMC transceiver board) | -| 15 | `15_QICKBox_RF_Daughtercards.ipynb` | QICKBox RF/Balun daughtercards: attenuators, ADMV8818 tunable filters, saturation checks (requires QICKBox with RF daughtercards) | - -## Usage - -1. Copy these notebooks to your RFSoC board (or run them directly from this location) -2. Start Jupyter: `jupyter notebook` or `jupyter lab` -3. Open the desired notebook -4. **IMPORTANT**: Change the `BITSTREAM_PATH` variable in each notebook to point to your firmware file -5. Run cells sequentially - -## Remote Execution - -For remote execution (e.g., from a PC), you'll need to start the QICK proxy server on the board first: - -```bash -python -m qick.pyro -``` - -Then in your notebook, use: - -```python -from qick.pyro import make_proxy -soc = make_proxy("board_ip_address") -``` -## Common Setup Cell (copy this to any notebook) - -```python -# Configuration -BITSTREAM_PATH = "/path/to/your/firmware.bit" # ← CHANGE THIS - -# Optional: remote execution -USE_PROXY = False -PROXY_IP = "192.168.1.100" - -# Connection -from qick import QickSoc -import numpy as np -import matplotlib.pyplot as plt - -if USE_PROXY: - from qick.pyro import make_proxy - soc = make_proxy(PROXY_IP) - print(f"Connected to proxy at {PROXY_IP}") -else: - soc = QickSoc(bitfile=BITSTREAM_PATH) - print("Connected directly to RFSoC") - -print(f"Firmware: {soc.get_cfg()['fw_version']}") -print(f"tProc cores: {soc.num_tprocs}") -``` - -## Notes - -* Notebooks 00–09 are self-contained and work on any QICK setup - -* Notebooks 10–15 require additional hardware resources (multi-board, streaming, DSP48, QICKBox) - -* Notebook 13 requires a licensed Vivado installation for custom firmware compilation - -* Notebook 14 (XCOM) requires additional hardware: FMC transceiver board and external hub - -* Notebook 15 requires a QICKBox with RF (and optionally Balun) daughtercards installed - -## Troubleshooting - -If you see "Bitstream not found", check `BITSTREAM_PATH` - -If tProc commands fail, try `soc.reset_gens()` and `soc.reset_adcs()` - -For proxy connection issues, verify the board IP and that the proxy is running - -If no signal in readout, check DAC→ADC loopback cables, verify `gen_ch` is correct - -Phase rotates with frequency, run electrical delay calibration (see [Notebook 07](./07_Advanced_Generators_And_Readouts.ipynb)) \ No newline at end of file diff --git a/docs/source/tutorials/README.rst b/docs/source/tutorials/README.rst new file mode 100644 index 000000000..c2ec127f6 --- /dev/null +++ b/docs/source/tutorials/README.rst @@ -0,0 +1,228 @@ +========================== +QICK Tutorials (Jupyter) +========================== + +This section contains practical tutorials for learning QICK and the tProc v2. +The tutorials are available as Jupyter notebooks and can be run directly on the RFSoC board. + +Prerequisites +============= + +- RFSoC board (ZCU111, ZCU216, or RFSoC4x2) with firmware loaded +- QICK installed (see :doc:`../quick_start`) +- Firmware bitstream file (`.bit` and its matching `.hwh`) for your board (this must have a tProc v2 core; some notebooks may require more specific features) +- Access to Jupyter notebook on the board + +Tutorials +========= + +.. toctree:: + :maxdepth: 1 + :caption: Basic Tutorials (00-05) + :hidden: + + 00_Getting_Started + 01_Basic_Sequencing + 02_Parameter_Sweeps + 03_Advanced_Timing + 04_Real_Time_Feedback + 05_Dynamic_Parameters_Subroutines + +.. toctree:: + :maxdepth: 1 + :caption: Intermediate Tutorials (06-09) + :hidden: + + 06_Generators_And_Readouts + 07_Advanced_Generators_And_Readouts + 08_Hardware_Buffers + 09_Appendix_Tips_And_Limits + +.. toctree:: + :maxdepth: 1 + :caption: Advanced Tutorials (10-15) + :hidden: + + 10_Multi_Board_Synchronization + 11_Streaming_And_RealTime_Processing + 12_DSP_Blocks_And_Correlators + 13_Custom_Firmware_Integration + 14_XCOM_Network_Synchronization + 15_QICKBox_RF_Daughtercards + +Tutorial Descriptions +===================== + +Basic Tutorials +--------------- + +.. list-table:: + :header-rows: 1 + + * - # + - Notebook + - Description + * - 00 + - :doc:`00_Getting_Started` + - Connect to the board, inspect hardware configuration + * - 01 + - :doc:`01_Basic_Sequencing` + - Define pulses, create sequences, acquire data + * - 02 + - :doc:`02_Parameter_Sweeps` + - 1D and 2D parameter sweeps + * - 03 + - :doc:`03_Advanced_Timing` + - ``delay`` vs ``wait``, auto-timing, avoiding collisions + * - 04 + - :doc:`04_Real_Time_Feedback` + - Conditional pulses, active reset, thresholding + * - 05 + - :doc:`05_Dynamic_Parameters_Subroutines` + - Virtual-Z gates, subroutines, dynamic updates + +Intermediate Tutorials +---------------------- + +.. list-table:: + :header-rows: 1 + + * - # + - Notebook + - Description + * - 06 + - :doc:`06_Generators_And_Readouts` + - Basic waveform generators, readout resonators, I/Q mixing + * - 07 + - :doc:`07_Advanced_Generators_And_Readouts` + - Muxed generators, PFB readout, dynamic readouts, fast dynamic readout, electrical delay calibration, IQ offsets, performance benchmarks + * - 08 + - :doc:`08_Hardware_Buffers` + - DDR4 and MR buffers, data capture + * - 09 + - :doc:`09_Appendix_Tips_And_Limits` + - Common errors, limits, debugging tips + +Advanced Tutorials +------------------ + +.. list-table:: + :header-rows: 1 + + * - # + - Notebook + - Description + * - 10 + - :doc:`10_Multi_Board_Synchronization` + - Synchronize multiple boards using external clock and external start signals + * - 11 + - :doc:`11_Streaming_And_RealTime_Processing` + - IQ streaming, on-FPGA averaging, real-time decimation + * - 12 + - :doc:`12_DSP_Blocks_And_Correlators` + - FIR filters, DDS tuning, hardware correlators + * - 13 + - :doc:`13_Custom_Firmware_Integration` + - Adding custom Verilog/VHDL, AXI-lite interface, rebuilding + * - 14 + - :doc:`14_XCOM_Network_Synchronization` + - Full mesh network for multi-board synchronization and low-latency communication (requires FMC transceiver board) + * - 15 + - :doc:`15_QICKBox_RF_Daughtercards` + - QICKBox RF/Balun daughtercards: attenuators, ADMV8818 tunable filters, saturation checks (requires QICKBox with RF daughtercards) + +Running the Tutorials +===================== + +1. Connect to your RFSoC board via SSH or JupyterHub +2. Navigate to the ``docs/source/tutorials/`` directory +3. Open the desired notebook +4. **IMPORTANT**: Change the ``BITSTREAM_PATH`` variable in the first cell to point to your firmware file +5. Run the cells in order + +.. note:: + + Don't have an RFSoC board handy? Tutorials 00-07 are also available + ported to the **QICK emulator** (``QickEmu``, a Verilator-based + software simulation of the firmware) at + ``emulator/notebooks/tutorial/*_emu.ipynb`` in the + `qick repository `_, + and can be run **directly in Google Colab** with no local install -- + each notebook's first "Colab Setup" cell clones the repo and installs + Verilator for you. See the emulator's + `README `_ + for details. Each emulator notebook's intro cell notes what had to be + adapted or skipped versus the hardware original. + +Remote Execution +================ + + +.. TODO: needs to explain starting the nameserver; I also suspect this is using make_proxy incorrectly and losing the soccfg object + we should update the pyro notebook and add that in here + +For remote execution (e.g., from a PC), you'll need to start the QICK proxy server on the board first: + +.. code-block:: bash + + python -m qick.pyro + +Then in your notebook, use: + +.. code-block:: python + + from qick.pyro import make_proxy + soc = make_proxy("board_ip_address") + +Common Setup Cell (copy this to any notebook) +============================================= + +.. code-block:: python + + # Configuration + BITSTREAM_PATH = "/path/to/your/firmware.bit" # ← CHANGE THIS + + # Optional: remote execution + USE_PROXY = False + PROXY_IP = "192.168.1.100" + + # Connection + from qick import QickSoc + import numpy as np + import matplotlib.pyplot as plt + + if USE_PROXY: + from qick.pyro import make_proxy + soc = make_proxy(PROXY_IP) + print(f"Connected to proxy at {PROXY_IP}") + else: + soc = QickSoc(bitfile=BITSTREAM_PATH) + print("Connected directly to RFSoC") + + print(f"Firmware: {soc.get_cfg()['fw_version']}") + print(f"tProc cores: {soc.num_tprocs}") + +Notes +===== + +* Notebooks 00–09 are self-contained and work on any QICK setup +* Notebooks 10–15 require additional hardware resources (multi-board, streaming, DSP48, QICKBox) +* Notebook 13 requires a licensed Vivado installation for custom firmware compilation +* Notebook 14 (XCOM) requires additional hardware: FMC transceiver board and external hub +* Notebook 15 requires a QICKBox with RF (and optionally Balun) daughtercards installed + +Troubleshooting +=============== + +* If you see "Bitstream not found", check `BITSTREAM_PATH` +* If tProc commands fail, try `soc.reset_gens()` and `soc.reset_adcs()` +* For proxy connection issues, verify the board IP and that the proxy is running +* If no signal in readout, check DAC→ADC loopback cables, verify `gen_ch` is correct +* Phase rotates with frequency, run electrical delay calibration (see [notebook 07](./07_Advanced_Generators_And_Readouts.ipynb)) + +See Also +======== + +- :doc:`../quick_start` - Quick installation guide +- :doc:`../topics/asmv2_cheatsheet` - tProc v2 cheatsheet +- :doc:`../topics/timing` - More details on timeline management diff --git a/docs/source/tutorials/index.rst b/docs/source/tutorials/index.rst deleted file mode 100644 index b158e07db..000000000 --- a/docs/source/tutorials/index.rst +++ /dev/null @@ -1,117 +0,0 @@ -========================== -QICK Tutorials (Jupyter) -========================== - -This section contains practical tutorials for learning QICK and the tProc v2. -The tutorials are available as Jupyter notebooks and can be run directly on the RFSoC board. - -Prerequisites -============= - -- RFSoC board (ZCU111, ZCU216, or RFSoC4x2) with firmware loaded -- QICK installed (see :doc:`../quick_start`) -- Access to Jupyter notebook on the board - -Tutorials -========= - -.. toctree:: - :maxdepth: 1 - :caption: Basic Tutorials (00-05) - - 00_Getting_Started - 01_Basic_Sequencing - 02_Parameter_Sweeps - 03_Advanced_Timing - 04_Real_Time_Feedback - 05_Dynamic_Parameters_Subroutines - -.. toctree:: - :maxdepth: 1 - :caption: Intermediate Tutorials (06-09) - - 06_Generators_And_Readouts - 07_Advanced_Generators_And_Readouts - 08_Hardware_Buffers - 09_Appendix_Tips_And_Limits - -.. toctree:: - :maxdepth: 1 - :caption: Advanced Tutorials (10-15) - - 10_Multi_Board_Synchronization - 11_Streaming_And_RealTime_Processing - 12_DSP_Blocks_And_Correlators - 13_Custom_Firmware_Integration - 14_XCOM_Network_Synchronization - 15_QICKBox_RF_Daughtercards - README - -Running the Tutorials -===================== - -1. Connect to your RFSoC board via SSH or JupyterHub -2. Navigate to the ``docs/source/tutorials/`` directory -3. Open the desired notebook -4. **IMPORTANT**: Change the ``BITSTREAM_PATH`` variable in the first cell to point to your firmware file -5. Run the cells in order - -.. note:: - - Don't have an RFSoC board handy? Tutorials 00-07 are also available - ported to the **QICK emulator** (``QickEmu``, a Verilator-based - software simulation of the firmware) at - ``emulator/notebooks/tutorial/*_emu.ipynb`` in the - `qick repository `_, - and can be run **directly in Google Colab** with no local install -- - each notebook's first "Colab Setup" cell clones the repo and installs - Verilator for you. See the emulator's - `README `_ - for details. Each emulator notebook's intro cell notes what had to be - adapted or skipped versus the hardware original. - -Remote Execution -================ - -To run the tutorials from a remote PC: - -1. Start the proxy server on the board: ``python -m qick.pyro`` -2. In your notebook, use: ``from qick.pyro import make_proxy; soc = make_proxy("board_ip_address")`` -3. Follow the notebook instructions, replacing the local connection with the proxy connection - -Tutorial Descriptions -===================== - -Basic Tutorials ---------------- - -- **00_Getting_Started**: Connect to the board, inspect hardware configuration -- **01_Basic_Sequencing**: Define pulses, create sequences, acquire data -- **02_Parameter_Sweeps**: 1D and 2D parameter sweeps -- **03_Advanced_Timing**: ``delay`` vs ``wait``, auto-timing, avoiding collisions -- **04_Real_Time_Feedback**: Conditional pulses, active reset, thresholding -- **05_Dynamic_Parameters_Subroutines**: Virtual-Z gates, subroutines, dynamic updates - -Intermediate Tutorials ----------------------- - -- **06_Generators_And_Readouts**: Basic waveform generators, readout resonators, I/Q mixing -- **07_Advanced_Generators_And_Readouts**: Muxed generators, PFB readout, dynamic readouts, fast dynamic readout, electrical delay calibration, IQ offsets, performance benchmarks -- **08_Hardware_Buffers**: DDR4 and MR buffers, data capture -- **09_Appendix_Tips_And_Limits**: Common errors, limits, debugging tips - -Advanced Tutorials ------------------- - -- **10_Multi_Board_Synchronization**: Synchronize multiple boards using external clock and external start signals -- **11_Streaming_And_RealTime_Processing**: IQ streaming, on-FPGA averaging, real-time decimation -- **12_DSP_Blocks_And_Correlators**: FIR filters, DDS tuning, hardware correlators -- **13_Custom_Firmware_Integration**: Adding custom Verilog/VHDL, AXI-lite interface, rebuilding -- **14_XCOM_Network_Synchronization**: Full mesh network for multi-board synchronization and low-latency communication (requires FMC transceiver board) - -See Also -======== - -- :doc:`../quick_start` - Quick installation guide -- :doc:`../topics/asmv2_cheatsheet` - tProc v2 cheatsheet -- :doc:`../topics/timing` - More details on timeline management From 4e18c2fd8e2a206147ef9e5969c2c04f3834a27b Mon Sep 17 00:00:00 2001 From: Sho Uemura Date: Fri, 11 Sep 2026 16:49:01 -0500 Subject: [PATCH 21/23] add tproc v1 to tutorials page --- docs/source/tutorials/README.rst | 123 ++++++++++++------ .../tprocv1/00_Send_receive_pulse.ipynb | 1 + .../tprocv1/01_Phase_coherent_readout.ipynb | 1 + .../tprocv1/02_Sweeping_variables.ipynb | 1 + .../tprocv1/03_Conditional_logic.ipynb | 1 + .../tprocv1/04_Reading_Math_Writing.ipynb | 1 + .../05_PhaseCoherence_QickProgram.ipynb | 1 + .../tutorials/tprocv1/06_qubit_demos.ipynb | 1 + .../tprocv1/07_Sweep_ND_variables.ipynb | 1 + .../tprocv1/08_Special_buffers.ipynb | 1 + .../tprocv1/09_photon_counting.ipynb | 1 + qick_demos/00_Send_receive_pulse.ipynb | 9 ++ qick_demos/01_Phase_coherent_readout.ipynb | 4 +- qick_demos/02_Sweeping_variables.ipynb | 4 +- qick_demos/03_Conditional_logic.ipynb | 4 +- qick_demos/04_Reading_Math_Writing.ipynb | 4 +- .../05_PhaseCoherence_QickProgram.ipynb | 4 +- qick_demos/06_qubit_demos.ipynb | 26 ++-- qick_demos/07_Sweep_ND_variables.ipynb | 4 +- qick_demos/08_Special_buffers.ipynb | 27 ++-- qick_demos/09_photon_counting.ipynb | 4 +- 21 files changed, 147 insertions(+), 76 deletions(-) create mode 120000 docs/source/tutorials/tprocv1/00_Send_receive_pulse.ipynb create mode 120000 docs/source/tutorials/tprocv1/01_Phase_coherent_readout.ipynb create mode 120000 docs/source/tutorials/tprocv1/02_Sweeping_variables.ipynb create mode 120000 docs/source/tutorials/tprocv1/03_Conditional_logic.ipynb create mode 120000 docs/source/tutorials/tprocv1/04_Reading_Math_Writing.ipynb create mode 120000 docs/source/tutorials/tprocv1/05_PhaseCoherence_QickProgram.ipynb create mode 120000 docs/source/tutorials/tprocv1/06_qubit_demos.ipynb create mode 120000 docs/source/tutorials/tprocv1/07_Sweep_ND_variables.ipynb create mode 120000 docs/source/tutorials/tprocv1/08_Special_buffers.ipynb create mode 120000 docs/source/tutorials/tprocv1/09_photon_counting.ipynb diff --git a/docs/source/tutorials/README.rst b/docs/source/tutorials/README.rst index c2ec127f6..878dad0dd 100644 --- a/docs/source/tutorials/README.rst +++ b/docs/source/tutorials/README.rst @@ -10,15 +10,26 @@ Prerequisites - RFSoC board (ZCU111, ZCU216, or RFSoC4x2) with firmware loaded - QICK installed (see :doc:`../quick_start`) -- Firmware bitstream file (`.bit` and its matching `.hwh`) for your board (this must have a tProc v2 core; some notebooks may require more specific features) +- Firmware bitstream file (`.bit` and its matching `.hwh`) for your board - Access to Jupyter notebook on the board -Tutorials -========= +List of Tutorials: tProc v2 +=========================== + +These notebooks must be run with a tProc v2 firmware. +Some notebooks may have additional firmware or hardware requirements: + +* Notebooks 00–09 are self-contained and work on any QICK setup +* Notebooks 10–15 require additional hardware resources (multi-board, streaming, DSP48, QICKBox) +* Notebook 13 requires a licensed Vivado installation for custom firmware compilation +* Notebook 14 (XCOM) requires additional hardware: FMC transceiver board and external hub +* Notebook 15 requires a QICKBox with RF (and optionally Balun) daughtercards installed + +Basic Tutorials +--------------- .. toctree:: :maxdepth: 1 - :caption: Basic Tutorials (00-05) :hidden: 00_Getting_Started @@ -28,34 +39,6 @@ Tutorials 04_Real_Time_Feedback 05_Dynamic_Parameters_Subroutines -.. toctree:: - :maxdepth: 1 - :caption: Intermediate Tutorials (06-09) - :hidden: - - 06_Generators_And_Readouts - 07_Advanced_Generators_And_Readouts - 08_Hardware_Buffers - 09_Appendix_Tips_And_Limits - -.. toctree:: - :maxdepth: 1 - :caption: Advanced Tutorials (10-15) - :hidden: - - 10_Multi_Board_Synchronization - 11_Streaming_And_RealTime_Processing - 12_DSP_Blocks_And_Correlators - 13_Custom_Firmware_Integration - 14_XCOM_Network_Synchronization - 15_QICKBox_RF_Daughtercards - -Tutorial Descriptions -===================== - -Basic Tutorials ---------------- - .. list-table:: :header-rows: 1 @@ -84,6 +67,15 @@ Basic Tutorials Intermediate Tutorials ---------------------- +.. toctree:: + :maxdepth: 1 + :hidden: + + 06_Generators_And_Readouts + 07_Advanced_Generators_And_Readouts + 08_Hardware_Buffers + 09_Appendix_Tips_And_Limits + .. list-table:: :header-rows: 1 @@ -106,6 +98,17 @@ Intermediate Tutorials Advanced Tutorials ------------------ +.. toctree:: + :maxdepth: 1 + :hidden: + + 10_Multi_Board_Synchronization + 11_Streaming_And_RealTime_Processing + 12_DSP_Blocks_And_Correlators + 13_Custom_Firmware_Integration + 14_XCOM_Network_Synchronization + 15_QICKBox_RF_Daughtercards + .. list-table:: :header-rows: 1 @@ -131,6 +134,52 @@ Advanced Tutorials - :doc:`15_QICKBox_RF_Daughtercards` - QICKBox RF/Balun daughtercards: attenuators, ADMV8818 tunable filters, saturation checks (requires QICKBox with RF daughtercards) +List of Tutorials: tProc v1 +=========================== + +These notebooks will run on the "standard" tProc v1-based firmware bitstream that is distributed with the QICK library. + +.. toctree:: + :maxdepth: 1 + :hidden: + + tprocv1/00_Send_receive_pulse + tprocv1/01_Phase_coherent_readout + tprocv1/02_Sweeping_variables + tprocv1/03_Conditional_logic + tprocv1/04_Reading_Math_Writing + tprocv1/05_PhaseCoherence_QickProgram + tprocv1/06_qubit_demos + tprocv1/07_Sweep_ND_variables + tprocv1/08_Special_buffers + tprocv1/09_photon_counting + +.. list-table:: + :header-rows: 1 + + * - # + - Notebook + * - 00 + - :doc:`tprocv1/00_Send_receive_pulse` + * - 01 + - :doc:`tprocv1/01_Phase_coherent_readout` + * - 02 + - :doc:`tprocv1/02_Sweeping_variables` + * - 03 + - :doc:`tprocv1/03_Conditional_logic` + * - 04 + - :doc:`tprocv1/04_Reading_Math_Writing` + * - 05 + - :doc:`tprocv1/05_PhaseCoherence_QickProgram` + * - 06 + - :doc:`tprocv1/06_qubit_demos` + * - 07 + - :doc:`tprocv1/07_Sweep_ND_variables` + * - 08 + - :doc:`tprocv1/08_Special_buffers` + * - 09 + - :doc:`tprocv1/09_photon_counting` + Running the Tutorials ===================== @@ -157,7 +206,6 @@ Running the Tutorials Remote Execution ================ - .. TODO: needs to explain starting the nameserver; I also suspect this is using make_proxy incorrectly and losing the soccfg object we should update the pyro notebook and add that in here @@ -202,15 +250,6 @@ Common Setup Cell (copy this to any notebook) print(f"Firmware: {soc.get_cfg()['fw_version']}") print(f"tProc cores: {soc.num_tprocs}") -Notes -===== - -* Notebooks 00–09 are self-contained and work on any QICK setup -* Notebooks 10–15 require additional hardware resources (multi-board, streaming, DSP48, QICKBox) -* Notebook 13 requires a licensed Vivado installation for custom firmware compilation -* Notebook 14 (XCOM) requires additional hardware: FMC transceiver board and external hub -* Notebook 15 requires a QICKBox with RF (and optionally Balun) daughtercards installed - Troubleshooting =============== diff --git a/docs/source/tutorials/tprocv1/00_Send_receive_pulse.ipynb b/docs/source/tutorials/tprocv1/00_Send_receive_pulse.ipynb new file mode 120000 index 000000000..c52dcab2c --- /dev/null +++ b/docs/source/tutorials/tprocv1/00_Send_receive_pulse.ipynb @@ -0,0 +1 @@ +../../../../qick_demos/00_Send_receive_pulse.ipynb \ No newline at end of file diff --git a/docs/source/tutorials/tprocv1/01_Phase_coherent_readout.ipynb b/docs/source/tutorials/tprocv1/01_Phase_coherent_readout.ipynb new file mode 120000 index 000000000..636e4eb32 --- /dev/null +++ b/docs/source/tutorials/tprocv1/01_Phase_coherent_readout.ipynb @@ -0,0 +1 @@ +../../../../qick_demos/01_Phase_coherent_readout.ipynb \ No newline at end of file diff --git a/docs/source/tutorials/tprocv1/02_Sweeping_variables.ipynb b/docs/source/tutorials/tprocv1/02_Sweeping_variables.ipynb new file mode 120000 index 000000000..0e70b1ed4 --- /dev/null +++ b/docs/source/tutorials/tprocv1/02_Sweeping_variables.ipynb @@ -0,0 +1 @@ +../../../../qick_demos/02_Sweeping_variables.ipynb \ No newline at end of file diff --git a/docs/source/tutorials/tprocv1/03_Conditional_logic.ipynb b/docs/source/tutorials/tprocv1/03_Conditional_logic.ipynb new file mode 120000 index 000000000..7baf01b21 --- /dev/null +++ b/docs/source/tutorials/tprocv1/03_Conditional_logic.ipynb @@ -0,0 +1 @@ +../../../../qick_demos/03_Conditional_logic.ipynb \ No newline at end of file diff --git a/docs/source/tutorials/tprocv1/04_Reading_Math_Writing.ipynb b/docs/source/tutorials/tprocv1/04_Reading_Math_Writing.ipynb new file mode 120000 index 000000000..e2352e48c --- /dev/null +++ b/docs/source/tutorials/tprocv1/04_Reading_Math_Writing.ipynb @@ -0,0 +1 @@ +../../../../qick_demos/04_Reading_Math_Writing.ipynb \ No newline at end of file diff --git a/docs/source/tutorials/tprocv1/05_PhaseCoherence_QickProgram.ipynb b/docs/source/tutorials/tprocv1/05_PhaseCoherence_QickProgram.ipynb new file mode 120000 index 000000000..655a7ad2f --- /dev/null +++ b/docs/source/tutorials/tprocv1/05_PhaseCoherence_QickProgram.ipynb @@ -0,0 +1 @@ +../../../../qick_demos/05_PhaseCoherence_QickProgram.ipynb \ No newline at end of file diff --git a/docs/source/tutorials/tprocv1/06_qubit_demos.ipynb b/docs/source/tutorials/tprocv1/06_qubit_demos.ipynb new file mode 120000 index 000000000..fb5cb874b --- /dev/null +++ b/docs/source/tutorials/tprocv1/06_qubit_demos.ipynb @@ -0,0 +1 @@ +../../../../qick_demos/06_qubit_demos.ipynb \ No newline at end of file diff --git a/docs/source/tutorials/tprocv1/07_Sweep_ND_variables.ipynb b/docs/source/tutorials/tprocv1/07_Sweep_ND_variables.ipynb new file mode 120000 index 000000000..ddf592d3d --- /dev/null +++ b/docs/source/tutorials/tprocv1/07_Sweep_ND_variables.ipynb @@ -0,0 +1 @@ +../../../../qick_demos/07_Sweep_ND_variables.ipynb \ No newline at end of file diff --git a/docs/source/tutorials/tprocv1/08_Special_buffers.ipynb b/docs/source/tutorials/tprocv1/08_Special_buffers.ipynb new file mode 120000 index 000000000..c1c5c62d4 --- /dev/null +++ b/docs/source/tutorials/tprocv1/08_Special_buffers.ipynb @@ -0,0 +1 @@ +../../../../qick_demos/08_Special_buffers.ipynb \ No newline at end of file diff --git a/docs/source/tutorials/tprocv1/09_photon_counting.ipynb b/docs/source/tutorials/tprocv1/09_photon_counting.ipynb new file mode 120000 index 000000000..36e9fe725 --- /dev/null +++ b/docs/source/tutorials/tprocv1/09_photon_counting.ipynb @@ -0,0 +1 @@ +../../../../qick_demos/09_photon_counting.ipynb \ No newline at end of file diff --git a/qick_demos/00_Send_receive_pulse.ipynb b/qick_demos/00_Send_receive_pulse.ipynb index 96f1b5617..3bdbc7545 100644 --- a/qick_demos/00_Send_receive_pulse.ipynb +++ b/qick_demos/00_Send_receive_pulse.ipynb @@ -1,5 +1,14 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 00 - Sending and receiving a pulse\n", + "\n", + "**Objective:** Verify your QICK installation, see signals in loopback, understand the different pulse shapes." + ] + }, { "cell_type": "code", "execution_count": 1, diff --git a/qick_demos/01_Phase_coherent_readout.ipynb b/qick_demos/01_Phase_coherent_readout.ipynb index d43fede95..9d99e37dc 100644 --- a/qick_demos/01_Phase_coherent_readout.ipynb +++ b/qick_demos/01_Phase_coherent_readout.ipynb @@ -4,9 +4,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#
      Calibrating the QICK for phase coherent readout\n", + "# 01 - Phase coherent readout\n", "\n", - "###
      In this demo you will calibrate the QICK clocks to have the same phase.\n", + "**Objective:** Understand the properties of QICK's \"phase-coherent\" generators and readouts, and practice calibrating their relative phase delays.", "\n", "Before you measure a resonance with your QICK this is the first calibration you should do. It is a calibration for the two synthesizers which belong to the QICK signal generator and the QICK readout, respectively. The two synthesizers are running at the same frequency, but there is initially a constant phase difference $\\phi$ between these two synthesizers. Doing this calibration results in you finding that phase difference $\\phi$. In your subsequent measurements, you can specify this initial phase difference $\\phi$ to compensate for it. From then on, the signal generator can synthesize any frequency and then if you read in data (doing a digital down conversion in the process), the readout will still be phase coherent with respect to the signal generator. \n", "\n", diff --git a/qick_demos/02_Sweeping_variables.ipynb b/qick_demos/02_Sweeping_variables.ipynb index 4b43203f8..ec015c25d 100644 --- a/qick_demos/02_Sweeping_variables.ipynb +++ b/qick_demos/02_Sweeping_variables.ipynb @@ -4,9 +4,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#
      Sweeping variables demonstration\n", + "# 02 - Sweeping variables\n", "\n", - "###
      In this demo you will sweep the amplitude of a pulse in loopback to demonstrate control over the QICK. \n", + "**Objective:** Sweep the amplitude of a pulse in loopback to demonstrate control over the QICK. \n", "\n", "We will sweep in two ways:\n", "* Within the QICK assembly language (advantage: faster, disadvantage: cannot be used to sweep the readout frequency)\n", diff --git a/qick_demos/03_Conditional_logic.ipynb b/qick_demos/03_Conditional_logic.ipynb index 906f01314..ca774b26e 100644 --- a/qick_demos/03_Conditional_logic.ipynb +++ b/qick_demos/03_Conditional_logic.ipynb @@ -4,9 +4,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#
      Conditional logic with the QICK demonstration\n", + "# 03 - Conditional logic\n", "\n", - "In this demo you will send and receive a pulse in loopback conditional on the value of a number written to the QICK. A similar application of the QICK conditional logic can enable the active reset of qubits. " + "**Objective:** Send and receive a pulse in loopback conditional on the value of a number written to the QICK. A similar application of the QICK conditional logic can enable the active reset of qubits. " ] }, { diff --git a/qick_demos/04_Reading_Math_Writing.ipynb b/qick_demos/04_Reading_Math_Writing.ipynb index fc81319c2..6f3ff1c4c 100644 --- a/qick_demos/04_Reading_Math_Writing.ipynb +++ b/qick_demos/04_Reading_Math_Writing.ipynb @@ -4,9 +4,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#
      Reading, math and writing demonstration\n", + "# 04 - Reading, math, and writing\n", "\n", - "###
      In this demo you will use the tProc to do some math and/or bitwise operations on two variables that you will pass in through the config dictionary and take out with single_read ." + "**Objective:** Use the tProc to do some math and/or bitwise operations on two variables that you will pass in through the config dictionary and take out with single_read ." ] }, { diff --git a/qick_demos/05_PhaseCoherence_QickProgram.ipynb b/qick_demos/05_PhaseCoherence_QickProgram.ipynb index a03058eca..81667d987 100644 --- a/qick_demos/05_PhaseCoherence_QickProgram.ipynb +++ b/qick_demos/05_PhaseCoherence_QickProgram.ipynb @@ -4,9 +4,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#
      Calibrating the QICK for phase coherent readout\n", + "# 05 - Calibrating the QICK for phase coherent readout (obsolete)\n", "\n", - "###
      In this demo you will calibrate the QICK clocks to have the same phase.\n", + "**Objective:** Calibrate the QICK clocks to have the same phase.\n", "\n", "Before you measure a resonance with your QICK this is the first calibration you should do. It is a calibration for the two synthesizers which belong to the QICK signal generator and the QICK readout, respectively. The two synthesizers are running at the same frequency, but there is initially a constant phase difference $\\phi$ between these two synthesizers. Doing this calibration results in you finding that phase difference $\\phi$. In your subsequent measurements, you can specify this initial phase difference $\\phi$ to compensate for it. From then on, the signal generator can synthesize any frequency and then if you read in data (doing a digital down conversion in the process), the readout will still be phase coherent with respect to the signal generator. \n", "\n", diff --git a/qick_demos/06_qubit_demos.ipynb b/qick_demos/06_qubit_demos.ipynb index 37ff75e75..51f0c16bf 100644 --- a/qick_demos/06_qubit_demos.ipynb +++ b/qick_demos/06_qubit_demos.ipynb @@ -4,7 +4,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#
      Qubit demos - working with a real qubit\n", + "# 06 - Qubit demos: working with a real qubit\n", + "\n", + "**Objective:** Practice tuning up a single superconducting qubit.\n", "\n", "The measurements in this notebook were used for the QICK paper https://arxiv.org/abs/2110.00557.\n", " \n", @@ -65,7 +67,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Helper functions" + "## Helper functions" ] }, { @@ -182,7 +184,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Configuring the channels\n", + "## Configuring the channels\n", "\n", "The data in this notebook was taken with a wiring diagram similar to the above. The QICK has eight RF DACs which can be configured in multiple ways. Using the QICK, two RF DACs are needed to control the qubit and its readout resonator, respectively. Also, the qubit control pulses (< 6 GHz) were directly synthesized without the use of an analog mixer. Note that the QICK RF board was not used for these measurements, only the ZCU111 evaluation board plus the analog components specified in the diagram." ] @@ -234,7 +236,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# TOF Measurement\n", + "## TOF Measurement\n", "\n", "Measures the \"time of flight\" of the measurement pulse. The time of flight is the time at which the measurement pulse appears in the ADC buffer. We only want to start capturing data from this point in time onwards. We store this time of flight in the parameter readout_cfg[\"adc_trig_offset\"] ." ] @@ -347,7 +349,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Single tone (Resonator) Spectroscopy\n", + "## Single tone (Resonator) Spectroscopy\n", "\n", "Measures the resonant frequency of the readout resonator when the qubit is in its ground state. We store this resonant frequency in the parameter readout_cfg[\"f_res\"] ." ] @@ -456,7 +458,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Single Shot\n", + "## Single Shot\n", "\n", "Measures the single shot readout fidelity of the system. We acquire single shot (I, Q) readout values by first preparing the qubit in its ground (blue dots) a certain number of times (in the below demo we take 5000 shots) and then preparing the qubit in its excited state (red dots) the same number of times. We then extract two parameters which are used to optimize the associated readout fidelity: the rotation angle of the IQ blobs and the threshold that classifies the two qubit states (ground and excited). We store these two parameters here readout_cfg[\"res_phase\"] and readout_cfg[\"threshold\"] .\n", "\n", @@ -598,7 +600,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Pulse Probe (qubit) spectroscopy\n", + "## Pulse Probe (qubit) spectroscopy\n", "\n", "Measures the qubit frequency f_ge. We store this parameter here: qubit_cfg[\"f_ge\"] .\n", "\n", @@ -718,7 +720,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Length Rabi\n", + "## Length Rabi\n", "\n", "Measures Rabi oscillations by sweeping over the duration of the qubit drive pulse. This is a preliminary measurement to prove that we see Rabi oscillations. This measurement is followed up by the Amplitude Rabi experiment below.\n", "\n", @@ -836,7 +838,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Amplitude Rabi\n", + "## Amplitude Rabi\n", "\n", "Measures Rabi oscillations by sweeping over the amplitude of the qubit drive pulse, which is an $\\approx$ 100 ns ($\\sigma$ $\\approx$ 25 ns) long Gaussian pulse. We measure the $\\pi$ and $\\pi$/2 pulse amplitudes which are used in subsequent experiments to control the qubit. We store these parameters here: qubit_cfg[\"pi_gain\"] and qubit_cfg[\"pi2_gain\"] " ] @@ -955,7 +957,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# T1 \n", + "## T1 \n", "\n", "Measures the qubit T1 characteristic decay time by preparing the qubit in its excited state with a $\\pi$ pulse followed by a variable delay ($\\tau$) before measuring the qubit's state. This exponential decay curve can be fitted in post-processing to obtain the qubit T1 time." ] @@ -1072,7 +1074,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Ramsey Fringe Experiment\n", + "## Ramsey Fringe Experiment\n", "\n", "Measures the qubit T2 Ramsey characteristic decay time by preparing the qubit in a superposition state with a $\\frac{\\pi}{2}$ pulse followed by a variable delay ($\\tau$) before applying another $\\frac{\\pi}{2}$ pulse with a phase advanced by $\\Delta \\phi = \\omega * \\tau$, where $\\omega$ is the Ramsey frequency. This exponential decay envelope can be fitted in post-processing to obtain the qubit T2 Ramsey time." ] @@ -1199,7 +1201,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Active reset\n", + "## Active reset\n", "\n", "This experiment demonstrates active reset with the QICK. \n", "\n", diff --git a/qick_demos/07_Sweep_ND_variables.ipynb b/qick_demos/07_Sweep_ND_variables.ipynb index 7bf1dea53..42442e767 100644 --- a/qick_demos/07_Sweep_ND_variables.ipynb +++ b/qick_demos/07_Sweep_ND_variables.ipynb @@ -4,9 +4,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#
      Sweeping over multiple variables demonstration\n", + "# 07 - Sweeping over multiple variables\n", "\n", - "###
      This notebook demonstrates how to run a ND variable sweep using the NDAveragerProgram.\n", + "**Objective:** Run a ND variable sweep using the NDAveragerProgram.\n", "\n", "When running parameter sweep experiments, to cancel the effect of slow drifting of room temperature electronics, we usually prefer to run all the sweeps in the fast FPGA program, and put the repetition as the last iteration axis. \n", "\n", diff --git a/qick_demos/08_Special_buffers.ipynb b/qick_demos/08_Special_buffers.ipynb index 9fbf84da0..d0dc75257 100644 --- a/qick_demos/08_Special_buffers.ipynb +++ b/qick_demos/08_Special_buffers.ipynb @@ -1,5 +1,14 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 08 - Special buffers\n", + "\n", + "**Objective:** Learn how to use the special (DDR4 and MR) readout buffers.." + ] + }, { "cell_type": "code", "execution_count": 1, @@ -156,7 +165,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# setup\n", + "## setup\n", "The board should be cabled in loopback; set the channel numbers and frequency here." ] }, @@ -175,7 +184,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# some notes\n", + "## some notes\n", "Remember that the QICK readout works in two steps: first digital downconversion (multiplying by a complex sinusoid), then decimation (low-pass filter and downsample to reduce the bandwidth and sample rate by a factor of 8).\n", "\n", "In normal readout, the decimated data stream goes to the average+buffer module which implements the \"decimated\" and \"accumulated\" readout modes. But we have additional buffer modules that can look at the data stream: the DDR4 and multi-rate buffers.\n", @@ -227,7 +236,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# example program\n", + "## example program\n", "This is identical to the 00 loopback demo, with the addition of the DDR4 and MR triggers. So the only lines you should look at are at the end of `initialize()`.\n", "\n", "You only need to trigger the special buffers once (later triggers are harmless but ignored).\n", @@ -306,7 +315,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# let's do a decimated readout\n", + "## let's do a decimated readout\n", "Note that if you arm a buffer and then run the program multiple times (such as by using soft_avgs/rounds, as we do here), the buffer will only start the first time.\n" ] }, @@ -408,7 +417,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## looking at DDR4 buffer\n", + "### looking at DDR4 buffer\n", "The DDR4 and decimated buffers capture identical data, but the DDR4 buffer has much more capacity.\n", "You generally won't use the full capcity of the DDR4 buffer; only arm and read what you need." ] @@ -480,7 +489,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## looking at MR buffer\n", + "### looking at MR buffer\n", "The MR buffer always captures and returns the full size of the buffer.\n", "\n", "We're looking directly at the output of downconversion, which is the result of taking the real ADC signal (which is the sum of two complex tones at positive and negative frequencies) and shifting it by the RF frequency.\n", @@ -544,7 +553,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# now let's do an accumulated readout\n", + "## now let's do an accumulated readout\n", "The DDR4 buffer is totally independent of the program execution, so you can use it with acquire() or acquire_decimated() - this is sort of naturally useful for debugging, since you can take your normal experimental program, just enable the DDR4 buffer, and capture many reps' worth of decimated data\n" ] }, @@ -617,7 +626,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# just triggering the buffer\n", + "## just triggering the buffer\n", "This is a minimal program that just triggers the buffer - so we just see noise." ] }, @@ -1001,7 +1010,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# extra: junk data\n", + "## extra: junk data\n", "The readout logic in both buffers hold some stale data - some data at the end of each readout is lost and shows up at the start of the buffer in the next readout. Normally this junk data is dropped, so you don't need to worry about it (you will just notice that you get slightly less data than you might expect).\n", "\n", "If we disable that cleanup logic, we can see the effect by doing one readout with a tone playing and a second readout with the tone off: the data from the second readout should just be noise, but instead we see the tone at the start of each buffer. We can confirm that the \"junk length\" configured in the QICK library is correct.\n", diff --git a/qick_demos/09_photon_counting.ipynb b/qick_demos/09_photon_counting.ipynb index b62e90f3a..ac36c2389 100644 --- a/qick_demos/09_photon_counting.ipynb +++ b/qick_demos/09_photon_counting.ipynb @@ -17,7 +17,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Edge counting\n", + "# 09 - Edge counting\n", + "\n", + "**Objective:** Learn to use QICK readouts in edge-counting mode.", "\n", "This demo shows how you can use QICK in a special \"edge-counting\" mode, where instead of integrating the I/Q values inside a readout window, QICK counts the number of rising edges inside the window. This functionality was developed by the [QICK-DAWG](https://github.com/sandialabs/qick-dawg) team for photon counting, but can also be used for counting RF pulses.\n", "\n", From 204ea6a3c2769f8620cc9e135e074caec0fef673 Mon Sep 17 00:00:00 2001 From: Sho Uemura Date: Fri, 11 Sep 2026 19:53:11 -0500 Subject: [PATCH 22/23] working on organization --- docs/source/index.rst | 38 +++++++++--------------------------- docs/source/modules.rst | 4 ++-- docs/source/topics/index.rst | 1 + docs/source/tprocv1.rst | 2 +- 4 files changed, 13 insertions(+), 32 deletions(-) diff --git a/docs/source/index.rst b/docs/source/index.rst index 95c7fb42b..f6ce1e713 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -60,15 +60,17 @@ The documentation is organized as a **progressive learning path** from beginner .. toctree:: :maxdepth: 2 - :caption: 1. Getting Started + :caption: Getting Started quick_start + tutorials/README .. toctree:: :maxdepth: 2 - :caption: 2. Tutorials + :caption: Technical References - tutorials/README + modules + topics/index The **firmware overview** is the map: which boards QICK supports, which cores live on each one, and how the tProcessor, signal generators, and @@ -77,9 +79,11 @@ specific core's page or the assembly-level tProcessor reference. .. toctree:: :maxdepth: 2 - :caption: 5. Firmware Overview + :caption: For Experts firmware/index + tprocv2_trm + tprocv1 The **readout system** turns ADC samples into the I/Q data your program gets back. QICK offers several down-converter and buffer cores with different @@ -103,42 +107,18 @@ core -- that don't fit into either the readout or signal-generator families above; see :doc:`firmware/support_cores` for what each one does and how (or whether) it's exposed to Python. -.. toctree:: - :maxdepth: 2 - :caption: 9. Python API Reference - - modules - -.. toctree:: - :maxdepth: 2 - :caption: 10. Technical Topics - - topics/index - The **tProcessor v2 reference manual** is assembly-level detail -- instruction encodings, register bit-fields, timing model -- for when you're writing or debugging tProc assembly directly, not something you need to read top-to-bottom to use QICK day to day. -.. toctree:: - :maxdepth: 2 - :caption: 11. tProcessor v2 Reference - - tprocv2_trm - **tProc v1** is the previous-generation tProcessor, superseded by v2 on all current firmware. Only relevant if you're maintaining pre-v2 code or firmware. .. toctree:: :maxdepth: 2 - :caption: 12. Legacy: tProc v1 - - tprocv1 - -.. toctree:: - :maxdepth: 2 - :caption: 13. Community + :caption: Community contact papers diff --git a/docs/source/modules.rst b/docs/source/modules.rst index 4e4cfb78d..771d35cd5 100644 --- a/docs/source/modules.rst +++ b/docs/source/modules.rst @@ -1,5 +1,5 @@ -Software API -============ +Python API +========== This page is the raw, auto-generated API reference -- every public class, method, and function in ``qick_lib``, with its docstring. For most tasks diff --git a/docs/source/topics/index.rst b/docs/source/topics/index.rst index b78425637..05242573c 100644 --- a/docs/source/topics/index.rst +++ b/docs/source/topics/index.rst @@ -1,3 +1,4 @@ +================ Technical Topics ================ diff --git a/docs/source/tprocv1.rst b/docs/source/tprocv1.rst index 64d38b2e4..3996c6b7e 100644 --- a/docs/source/tprocv1.rst +++ b/docs/source/tprocv1.rst @@ -1,5 +1,5 @@ ======================================================== -tProcessor v1 (axis_tproc64x32_x8) - QICK Firmware +tProcessor v1 (axis_tproc64x32_x8) - legacy ======================================================== .. contents:: From 50d5834ef6a7531a624b5c022fd4f61ba92dfd3e Mon Sep 17 00:00:00 2001 From: Sho Uemura Date: Fri, 11 Sep 2026 23:34:10 -0500 Subject: [PATCH 23/23] move stuff into "beta" and "alpha" sections, etc. --- docs/source/alpha.rst | 17 ++++ docs/source/beta.rst | 28 ++++++ .../example_code.rst => contributions.rst} | 11 +++ docs/source/index.rst | 97 +++++++++---------- docs/source/topics/index.rst | 15 +-- docs/source/tprocv1.rst | 2 +- docs/source/tprocv2_trm.rst | 2 +- docs/source/tutorials/README.rst | 4 +- 8 files changed, 107 insertions(+), 69 deletions(-) create mode 100644 docs/source/alpha.rst create mode 100644 docs/source/beta.rst rename docs/source/{topics/example_code.rst => contributions.rst} (67%) diff --git a/docs/source/alpha.rst b/docs/source/alpha.rst new file mode 100644 index 000000000..6323aa861 --- /dev/null +++ b/docs/source/alpha.rst @@ -0,0 +1,17 @@ +=============== +Alpha features +=============== + +These are features or components that are still under development. +They are generally only being used by QICK developers and possibly one or two early testers. +These features may require hardware or firmware that is not yet publicly available. +Documentation provided here may not reflect the current state of development. + +XCOM board-to-board communication protocol +========================================== + +.. toctree:: + :maxdepth: 1 + + topics/xcom + topics/XCOM-commands diff --git a/docs/source/beta.rst b/docs/source/beta.rst new file mode 100644 index 000000000..fd570a493 --- /dev/null +++ b/docs/source/beta.rst @@ -0,0 +1,28 @@ +=============== +Beta features +=============== + +These are features or components that are being tested by the QICK community. +There may be bugs, documentation may be incomplete, and updates may break compatiblity with experiment code you write now. +Firmware components in beta are not included in the "standard" firmware bitstreams, but firmwares with these components may be available on request. + +tProcessor v2 +============= + +Version 2 of the QICK tProcessor supports more output channels and allows more flexibility in writing QICK programs. +The assembly language, and therefore the Python API, for tProc v2 are incompatible with those for tProc v1. + +.. toctree:: + :maxdepth: 1 + + tprocv2_trm + topics/asmv2_cheatsheet + topics/tprocv2_migration + +Also see the following pages, which have separate sections for tProc v2 material: + +* :doc:`tutorials/README` +* :doc:`modules` +* :doc:`contributions` + + diff --git a/docs/source/topics/example_code.rst b/docs/source/contributions.rst similarity index 67% rename from docs/source/topics/example_code.rst rename to docs/source/contributions.rst index a728162ad..a20b6807c 100644 --- a/docs/source/topics/example_code.rst +++ b/docs/source/contributions.rst @@ -1,3 +1,14 @@ +=========================== +Community contributions +=========================== + +Extensions & Customization +=========================== + +- **QCoDeS Driver**: Save instrument configuration (`QCoDeS-QICK `_) +- **QICK-DAWG**: NV centers and quantum defects (`GitHub `_) +- **SpinQICK**: Solid-state spin qubits (`GitHub `_) + Example code from the community ================================= diff --git a/docs/source/index.rst b/docs/source/index.rst index f6ce1e713..9ddbd58bd 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -45,14 +45,6 @@ Quick Links - **QICK Paper**: `arXiv:2110.00557 `_ - **Community**: :repofile:`Contact & Support ` -Extensions & Customization -=========================== - -- **Pyro4 Server**: Persist board state across notebooks (`Pyro4 demos `_) -- **QCoDeS Driver**: Save instrument configuration (`QCoDeS-QICK `_) -- **QICK-DAWG**: NV centers and quantum defects (`GitHub `_) -- **SpinQICK**: Solid-state spin qubits (`GitHub `_) - 📖 Documentation Navigation ============================ @@ -60,6 +52,7 @@ The documentation is organized as a **progressive learning path** from beginner .. toctree:: :maxdepth: 2 + :hidden: :caption: Getting Started quick_start @@ -67,76 +60,76 @@ The documentation is organized as a **progressive learning path** from beginner .. toctree:: :maxdepth: 2 + :hidden: :caption: Technical References modules topics/index -The **firmware overview** is the map: which boards QICK supports, which -cores live on each one, and how the tProcessor, signal generators, and -readouts fit together on the FPGA -- read this before diving into any -specific core's page or the assembly-level tProcessor reference. - .. toctree:: :maxdepth: 2 + :hidden: :caption: For Experts firmware/index - tprocv2_trm tprocv1 - -The **readout system** turns ADC samples into the I/Q data your program gets -back. QICK offers several down-converter and buffer cores with different -tradeoffs (software- vs. tProc-configured, on-chip BRAM vs. DDR4 capture, -plus a resonator simulator for hardware-in-the-loop testing) -- start at -:doc:`firmware/readouts/index` for the concepts and the normal ``declare_readout()``/ -``acquire()`` workflow, then dip into a specific core's page for register- -level detail. - -The **signal generators** turn your program's pulse definitions into DAC -output. QICK offers both single-tone arbitrary-envelope generators (for -shaped pulses) and multiplexed fixed-tone generators (for playing several -simultaneous tones from one channel) -- start at :doc:`firmware/generators/index` for an -overview of which core fits which experiment, then see :doc:`firmware/generators/sg_v6` for the -full worked Python examples shared across the family. - - -The **support & utility cores** are smaller IP blocks -- a constant-IQ tone -source, a tProc-output register/trigger helper, and an AXI-Stream buffering -core -- that don't fit into either the readout or signal-generator families -above; see :doc:`firmware/support_cores` for what each one does and how (or whether) -it's exposed to Python. - -The **tProcessor v2 reference manual** is assembly-level detail -- -instruction encodings, register bit-fields, timing model -- for when you're -writing or debugging tProc assembly directly, not something you need to read -top-to-bottom to use QICK day to day. - -**tProc v1** is the previous-generation tProcessor, superseded by v2 on all -current firmware. Only relevant if you're maintaining pre-v2 code or -firmware. + beta + alpha .. toctree:: :maxdepth: 2 + :hidden: :caption: Community contact + contributions papers -Learning Path Recommendations -============================== +.. TODO: too verbose for front page, should move to firmware page (also the prose reeks of LLM) + The **firmware overview** is the map: which boards QICK supports, which + cores live on each one, and how the tProcessor, signal generators, and + readouts fit together on the FPGA -- read this before diving into any + specific core's page or the assembly-level tProcessor reference. + + The **readout system** turns ADC samples into the I/Q data your program gets + back. QICK offers several down-converter and buffer cores with different + tradeoffs (software- vs. tProc-configured, on-chip BRAM vs. DDR4 capture, + plus a resonator simulator for hardware-in-the-loop testing) -- start at + :doc:`firmware/readouts/index` for the concepts and the normal ``declare_readout()``/ + ``acquire()`` workflow, then dip into a specific core's page for register- + level detail. + + The **signal generators** turn your program's pulse definitions into DAC + output. QICK offers both single-tone arbitrary-envelope generators (for + shaped pulses) and multiplexed fixed-tone generators (for playing several + simultaneous tones from one channel) -- start at :doc:`firmware/generators/index` for an + overview of which core fits which experiment, then see :doc:`firmware/generators/sg_v6` for the + full worked Python examples shared across the family. + + The **support & utility cores** are smaller IP blocks -- a constant-IQ tone + source, a tProc-output register/trigger helper, and an AXI-Stream buffering + core -- that don't fit into either the readout or signal-generator families + above; see :doc:`firmware/support_cores` for what each one does and how (or whether) + it's exposed to Python. + + The **tProcessor v2 reference manual** is assembly-level detail -- + instruction encodings, register bit-fields, timing model -- for when you're + writing or debugging tProc assembly directly, not something you need to read + top-to-bottom to use QICK day to day. + + **tProc v1** is the previous-generation tProcessor, superseded by v2 on all + current firmware. Only relevant if you're maintaining pre-v2 code or + firmware. **New to QICK?** Start here: 1. Read the :doc:`quick_start` guide to set up your board -2. Complete the **Basic Tutorials** (00-05) to understand core concepts -3. Work through **Intermediate Tutorials** (06-09) for practical measurements -4. Read :doc:`firmware/index` for the big picture, then explore **Advanced - Tutorials** (10-14) for specialized applications +2. Complete the :doc:`tutorials/README` to learn core concepts and apply them in measurements +3. Read :doc:`firmware/index` for a big-picture view of the QICK firmware **Already familiar with QICK?** Jump directly to: -- :doc:`firmware/readouts/index` and :doc:`firmware/generators/index` for the readout/generator hardware +- :doc:`firmware/readouts/index` and :doc:`firmware/generators/index` for the readout/generator firmware reference, organized by which core is on your channel - :doc:`modules` for full API documentation - :doc:`topics/index` for deep dives on specific topics diff --git a/docs/source/topics/index.rst b/docs/source/topics/index.rst index 05242573c..9f4502a28 100644 --- a/docs/source/topics/index.rst +++ b/docs/source/topics/index.rst @@ -19,24 +19,14 @@ These topics assume you have completed the basic tutorials (00-05) and are famil gen_config readout_modes units - reference_clock - changing_fs - -.. toctree:: - :maxdepth: 1 - :caption: Quick Reference - - asmv2_cheatsheet - tprocv2_migration - example_code .. toctree:: :maxdepth: 1 :caption: Advanced Topics - xcom - XCOM-commands pyro4 + changing_fs + reference_clock Topic Descriptions ================== @@ -98,6 +88,5 @@ When to Use Each Topic - **Using external clock?** Refer to :doc:`reference_clock` - **Writing assembly code?** Keep :doc:`asmv2_cheatsheet` handy - **Coming from tProc v1?** Start with :doc:`tprocv2_migration` -- **Looking for full example experiments?** See :doc:`example_code` - **Synchronizing multiple boards?** Read :doc:`xcom` for the network-based solution - **Need XCOM command details?** See :doc:`XCOM-commands` for the complete command reference diff --git a/docs/source/tprocv1.rst b/docs/source/tprocv1.rst index 3996c6b7e..0bacf0e40 100644 --- a/docs/source/tprocv1.rst +++ b/docs/source/tprocv1.rst @@ -1,5 +1,5 @@ ======================================================== -tProcessor v1 (axis_tproc64x32_x8) - legacy +tProcessor v1 (axis_tproc64x32_x8) - reference manual ======================================================== .. contents:: diff --git a/docs/source/tprocv2_trm.rst b/docs/source/tprocv2_trm.rst index 04a60e8b7..b61a1e649 100644 --- a/docs/source/tprocv2_trm.rst +++ b/docs/source/tprocv2_trm.rst @@ -1,7 +1,7 @@ .. _tprocv2_trm: ================================================== -QICK tProcessor v2 - Complete Reference Manual +tProcessor v2 - reference manual ================================================== .. meta:: diff --git a/docs/source/tutorials/README.rst b/docs/source/tutorials/README.rst index 878dad0dd..0b48a8eea 100644 --- a/docs/source/tutorials/README.rst +++ b/docs/source/tutorials/README.rst @@ -2,7 +2,7 @@ QICK Tutorials (Jupyter) ========================== -This section contains practical tutorials for learning QICK and the tProc v2. +This section contains practical tutorials for learning QICK and the tProcessor control core. The tutorials are available as Jupyter notebooks and can be run directly on the RFSoC board. Prerequisites @@ -191,7 +191,7 @@ Running the Tutorials .. note:: - Don't have an RFSoC board handy? Tutorials 00-07 are also available + Don't have an RFSoC board handy? Tutorials 00-07 for tProc v2 are also available ported to the **QICK emulator** (``QickEmu``, a Verilator-based software simulation of the firmware) at ``emulator/notebooks/tutorial/*_emu.ipynb`` in the

      >F)|iEAaw=P1_2j#Mn3ibM93;wzrS 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�6-(rVan}Smw08Fq8+WLU;O8Wq)GNj}mfQbYg)lVkl z%MQ+KwQGk9Je0ZcR$Y9-5@7-lK!RyVN|66~%gn7P$x}k%Row`=e$(CP%<*=J|OlAz+}k{&y#Aa+bo9_rr|qkh3SGiEF6= zdg|Q41`%)9^+drh4QfZi3i^Z>^sOe#}iSjwU z8nedvZe`K_Hf5~L7d5>+jKWM;m&;|Rwb}O#v}IG2l`6O>@b236u(E$8|6x!=k!Vlk z^E9DB1X39#G|k3WIc+D(dMxqD%=INU^rPGpfS4BIJ_Qa0fveVy>Q*agA^YX#p1#{g z8~so*Ob&upB~uhz5>yH|@v><^xhp9c=Jb&4wynG zx=Qn#ls3foL0R0H)Z_eGqu16ulzeC3`-Y>`Z)K$1@iG*!yzZMR_5)B3yJ?KwS`0Xo3ifz5>0XW*Gd0>QH}jo)n2<~UfD&-x$ZtY_i>j%MeWWK z=lUe;GmPrm@h@?4^^G`%G#}7B@ff;e{c*h{4eTKv#=2bQ=J}D#^4D?N#$lg@;hvq- z|50cEUn$(bQu_ZLUiq)S{AFg26%bQ zVlz-(UH92;06+r!0N3+}Q`?sKvZtEttACAgW4-;TwW&WxgMa>TM~}~ZmOuVcbw{t@ zx-odsKV;XBSYla6!=;luK_~6jeLLF+mx1)JhKB18%k|cHjCP^6goFhC;Lo1=+S}X9 z5-z@}$u-OqJmKcdef~Bf!p#vO_x8p{5+INJx!2eF$lR?kAci+v=vwZywS!aC7^B+r@QbCTIM4@w2`BL^vB$>oNa? z`m@{pNt|;_PI#2__ym(SHn6cc0yUs5k-rwjHmb*Mtd>i_2JT zFMpx--xgnA@j~G3yl>ZryBz;4`1tLv^g*bJf8LnCq zpoLfZ`#CP@Lw?+$fh}|=AV>8W%W^PLH`6ML#8om}YghXuah-Z|N1gDgD_)e6vBmi4 zF^f^X+Plllnr5N(cC&2klDavD=A5hH`Q++u-;D$W_5>u7{d=C zd-_Jq?y{(#&dHGD4yEHiO-_s^J!LWWi40~(CwqzHMnk%KLncRmZ)mqJgc@b^nY2NT zA~d81p&z+x*;DHAi&CPUR%%*UOZUK9w6-a;OHYZs3X+3iU?(%O`I1*!`Gf}1MM7xB zhalF767A7m0HvUybnpt#H519N)KrB5vH-~^!>?KSKs`xjpplSXYzjgS zW<$h`Y1UQ)!XqV*3$}^WPv|K$p*zElRje+z!tpuNUWX;eE(>=uw4z48=Lx0KUZ0nK zh@k2;^kGCA``Apc50yhG_mLD|CLxHLv7BHxQ)24TF$|}yl1SV&sm3n^F`mKBseXm5 zHR@?*`M9cO^md>$gShVqf$Ov)$UF=yLWhm|I5$++%T^_dZo0jYe}>6ZF!e7G9v;nH zc7rW134wRt(^?kbI(ZhQV9nnCUM;Phk4Oep8WPT62|*cb zl>Z266XAz3EWtyQDU|iLbV4Q)0-nxf;_5AB(pFF;IVki6`i1`DfCux-AzY1X_`#R~ z+}7YJvNE_d;T@YMc&Yd03e}_K%K+}Ws#*Jd8kF8xYB0RH2l()9AwPyOkFsBjGpe{d z&}dfpSb-0hLEJ8px~qH*G;B>CsS7$7kztb<7@Yh)AX&O`;u_T9k=Png#Jp3;YxV4f zQxf_q0F*I)_B77P=WS2*+7s&K_KjS%S}M}dgZ`r1MCKev!PqdwPBcTuY3f@&NN+Ek zP$5_oh#km`)vKFu!}$*So*(gr|~R?4I>);RGsP`h*lplJzB8isEmXH%TcTnCwR zR>LPo?ITi6Mj^OV*=ms@9$e}Xzs}*=Tfim}YY9s# zq(2vl*$svVRabLG3JQ)o^#T}dN*HoidO;HK8M3eSqt2-#NP_yB+Mo?1UqVjqu7pGb z?c~}uOoaDrhxOh#ZKfg?ltJl5Gn|oT_D%@ebBm<|i-0W0tmT zvjUFG-h$EODFx)L_Li`%NvBY9LqTb8Us_7B>sqOh{{TZd%7){N22mywA^k<66(+G7 z-4(h^*Tbtu-*r43vmG!ze+N5GTfDjJX170+n-o}zH488=os z$Voh|yyY*+S7ZN5P<=HufY;6b7OKi%gvHXxkx?^b$U$<~yI_N)?Y3(^NUE@MAg!wr zwg)9)v25v9vXoqJL%LF4KrDzwZ5kkWVXp1w`4A1u!W;oRq~|CPrB#95TX~vN<@WlV zzOc@v4(}NH93AA0f7`5#xEnOA?ez8LE>y!k9yT5Pz0=_LA9B}1@;ooUUKn+_5c_>? zkUzi zHXzakadGRdt%d~ZTYB=)?+4P#^Kwbji!iie$Bh6{>$W9{*9XVMxNf*`^HMus>nUZM z?rKSDe7NhK&REw8SQZOI{zH|v<|f6aUKeRxCDyvE-=Fy!HvKIuxqjvn=8AiC{@B2M zNSeYu8tQnqDQLT>-OJW)L3OI)OHUNZKVJcU{b5eP!;+cC6rF`pgiiXqJPV_@e^P4H z2K*YKxJ9wla=TM9yk#46He!4vNypaZF6Le%aI;7S{#_UhK%NN?}q($3q# zU*YzjxR{V3p4!W6w_xw>>pV*WZtX$_>RjH#NJXUxq-3(|(Z<0q_E77?e82hDPX<2zSa27PpDtpq)){i zNJRNyt@1}^sr|bS%{t(Z3KY}&#pDnlRlG`VReh3{*d#?&xp^6;+?Iq$9XY^qf4om(r?5+hw&T2EB@`gFIE zo@adw7-xu_R-8emA)>^5?<_mYh;EErxf!+WpT0#Ok1jxOP5(CBmRc9PoVq(Lz5ui& zg0MDqHnJK6FlFJ{R@EyKx^jtxSJSCZ=TyDym%*3Qm5K?Ek`j<^7Rx!gG#;+~sa^f~e8 za7xzWM5+m*qSgW0<*KxaQb!Mt$*)|toL2@UhBQ2tTgY~I7ReeEP?u5zJj6m@m)0%r zgLao7KgVg1uP$5?QG!$oZqYId1jfP%!Ct8aK^xj8+8CI}H@?K8#YF3nD)?EIBC^kn zTrq9(DcyH!DGaW^8eO}bqv_#{#XA^C-rQ3pHAq_Jg?^mYqCX}1yxd9;UQ7P;_Unp; zWfjp|_518;DPPhl*Z?>;q+*2`)6Kq}@kYP@yE&F7rjB+M=c`?LB9c7KU?!>SXTS|j zkB%uCTW+t+Wj|K1DpbnwFZJ=fqCRuM(!<9Zy^eWft9b$`>dFJ2d!^+;s2uo!u)!C@M-8b%|MGGEb_mexG+Zpx1O$Yna_n^3aSGfKI$%oi)@5v-D^>v#a8JLW2YDvJoR= z6TQC))#L%_RR}aKTbLh$>|%z@ckiy6n~zX7CoRQgR)W-vG<~}UZWnl&tR?V} z*GJSI^kp8x;Tm24AUR5|)adwG2i^OoFK%sSid}cg{oECuY)9rlhf(KxKCS|d$3M!E zhwOfuvT{`X zkcAY!q;I!-$@_FkOKRGY?az14k&b@J@RI=+zy)Ci(Ut=yC@V{1Be$VR6_s0vO{@LB z5oKV}x`$49-$`+w6P;Ejz(M;drrYCv3SKV_CgyrihZ* zmtO6wv{@*cOryhUy}Hhe$X1s-Y(=b6Dr|M#(cdJ$s=t)C8?Ci%@K%)enTya|gHrs@ zBq$QE50TR1vU4||Ly43>L82iw`*8Wz>Ak^6;l-s`nO8!ZZ5Rn&TnoFfH6UEC-m2XzS33^glDxM(G|1-{WQX1=l$DrNFA! zga;?!>+>_<_`J?UTa@<0!@%(lP;m;@lmV=oL|M{L9{?AZfs($(E)m!EB%sGK)OV?1 zW;iAmiH7U->zvU9$7~G;+yaTn+LfncXmZR3HO=c3H~~yk$>|Py^MGWKh>_G{JyV6U z6}vg1g*UCE?9|GAN~N0*`_vL4Y@^Vb`I-^y)uXxY?v-{ese61U$(rl83x#heCk=^G z6XutX)BrS(If!LTmO5o7YQT%2o@t*`3PhAAs)~fvFwnt z{kW_7`X~6Uh@jwHLJQ?ps~igM;kXvq?cke%6^&| z4ji|S;#qNVN}Q4YkK}I=zz@eXr#8mhLChOtC5E$EyK`g*)2bLHYuZX>x_yce}?fdE};(#2)o44TAmKY>+91cEhw z!uKQ{)E;xrN~}9g*;G>m8ix}}+gc+@%E}HjI;#K9wIBT9!v{|_&xNmjjTQqw?&5RB zZ^Xd8+id$se$s)i z^zB%0f_i>V%qFL@igSejPyWtXvk%Y02%7Gs9^8*g8K@?RwY}BBsg2^4YjJUXPA(}a zNsHnXDy_@xisuvo-IWFP49<3^AVq(^_OuZvBmi9;Ho1QNIzYc=i$nbnXXF08+&sqT zjQ(=*W~vxFG;!iVU#wje>2o>AtT_YDjq2b2PHB1m-G6;3@mupxe1E+3PSn3{>;L3p z{IA@u|I;}CO`HF}?AQIpk^P@M{aLem@3J5H4r{aB1DyI6r~d=ArbkH207m^!NVz&b zB|W`>N^R53fNA}3{TdX5IbT1HOqDpVrWZOpDOg<33$Jisd%nMzvX3XA>ZeKf+|Kw; zPtd1j?yoxY|Rtm6N~<0jv}*FiZU4$e+dj@}(t z!YM%_52F!(Rdrm@KN7vRIae<8BN>Oo5}~U&Jin+JD!86dq2gbR77mE@;;=m_c3iQr{FKZQ4hCFx>%~@9koEoo(qkT#0@P@0hvdqqnr%?CL+%o1mT+hklBS*1S3B^(W zE=kk)!hove>>Hs46*FI;#p>%YRqtmop9Pj)26@v*0AU>yC(D2<%}kmpEv_g-eG@%q zkg0ilWUz*HBhn8978@4zervnXP9wrm4KRivY8qC+kYQO#^(fzk)h!}Jf_12)Pff|S z>N35bT|q_1t;1a6yUi=@@g+$PZ^s@c9gn;QT2g5@PlZBy--n@4S+hOXCAa-NOtiJb z8{t)09mV^%*wH>@4`w@gKZJTbi{5!LnIy67{)3;NUoC!>+7_CjSD3`jW8`=_49PdL zC1{hYGC4cxd`o4tNy=4at3zQs3Rm=fyg2Z7fxg`M)EnO=IvAex|0th!8=Fwx#gfJ^4tug@ouD66cqol%=YIv+-Yi(md|v&r&q_j;=xnZ=DN1wAI^W|Y-t~tr62wY zlZN)`K-0HXii#5(v{I_#FYmg%xEq#8;gq4-)ez@Hu7T_ChgUo%U*Nk=*(I{RPN{Wc z0|Dya&R)6F1dO?QH3i{B5d_xy$8+M$2v5H%8Z#2Gt>3@-(sIN^$-O4Wt+u^FTw1H> z_#)2F0D?=B)kM6T`9WJ|Na2G-<6F~zQ5KqfP}9ic#@%}cDFf`h=JP7WQKr|!dG{=O zjGro}GG$UER}Li<*kpXmJS3f3{M0JI=!_o#HL%OZ2ALPrRE*jPg4WgEbrP}X~@2wikQ(mq&@)`wN(H?&PGDW3Z{Y>f`+*c~2 zc)2cXVTT$)P220nZ-+-cCU8{hq>;5fCT$OO&?tkq2cN-iFhjBGwMSMx?U*t4LSAj| z$$$fdpcUtV1yU$wbEImncm+iXceXz)Y*Augp3fTM4c<~-ZwqXULpvlj!kg)6x?lSf zo8>PiPXaYL0)36vmiwuNKGB>}@jXMgL*jyQPktVKD?$wYIOB~&hpGP$yaxAg(|B%1 zr+OZpoadLj^2P#KlS{`Mhux7A8GenTB# z8B@a7VZ=JC>dJiBowOAg0xiT)()UBL{eCZKi8s0s834`2jivEMpY`ODBLGO592fwG z;EP@jhXM-*aew*fsn7U zd7gppk7%*MZSNoTx<3m3>V4L(J^ILnP*z$aVNGpq^Wj4QC40M^F9^pBEOF#X*7>$F ztHnEPA}Rm7!O$;?nn`izGTzRgQ-DhzsY0PclI_+KoPafM@jqk)NA)S>BzkEh67y}l zleZ!c>K%Yv-M=~hL#n}iEcuIm|NQCtkFB@xz{S&~m5G8w?LQ`xI^bWh38I?v`e6LxS)wK#IRP*H2O}GbNX$j$JoA+XA{}|Nxlfx(8ANoto z+&J;u$@_TSjLzi{>`X~*h8X8QS6q-HD)E`%J%?I8&QhEFtAO?S!%zEo-VS;k=givY z13#K^g2EwzxA`;;2P|I|DDT(&>)PkjSZg?QMlR7LSpky1d*87~|ItiLCSLJc;p_BM z!N^nlwRC@ox*I2glsS@keKCS$4vrU>lmwHWa{fC5v(qH6cH23!_3xN4nD2ra#+N#X z2AhI^ZrTRve?xLXanSgz+-R_O?Jn1Sk%2+Ve`oq;`W6-j?n*Q+e!&^a52^9bP&Ave zLQWOUOMe~^d3EM5y1$*w-^$N57m7cXBCe0R)wzazH~x!5weI~RC&u94x6`^MjMe{(C6~gJklW9e;yM6%&`shxiv}E1-U*m89t{bF-wOefj6kpC`X77hA9T zt$B$Sb!3{vFfVy^ttcryc^p!he$TLOm+K!thxmNtN^{fXiubnEJC6PZkKo?H?62E5 zboU!^c1nTwBhLPmq3c^LKy18RQO&8kk3<8^+g#6o&`bVg?eZ!fvK(qy1^6ID(5F^~ zKeBc%QabZrKpkR)U|Q$u-Woi7SQr@iJDj(*DxR(HWA{#|QByMFtmSbgmd?jK;qEY7{N#4ET}KDLg%dOo;-5cS@b{rHh6~v zi{eavB4=tiDpeWeu!xu#>gCHn;JoM0m~DES(fkV zUpq93Oq+07?`7PQFL*TNDJjXgdav&?V1_ubuICx7jH^m}Yw z`x?O-?!(K=D+g!!^BueVQ7HV)b--Uj<`RNWxg-6H@?yB@`qCj15Io^-B|VRDtpe&C zX_l7%qbK0c*0XZAErldfS@&pnTYiqL%q`V_Mwq_Q(jjvZWMi}Fzwosz2VPSg$FT%{ zGJ`?6$(^35PMOB(8149?OR~ou&z+N747{27@m3)7n1i3OXv`pIWxhDMdfwq#h-Uih z9|;ds?!BNCa;Z{%NQX-3!-yndwWmK`wm;~CqVZ|jh^7XfpwR_ZjACqZPxgz^!0!7O zkcBt;vdBNV=heHX;*V5+i+p)0_1@qQImDHHqbVz9hz4<~jQK;yA^G>9^6L!87gLpw zey~K#Um#sUuJF;N36dy+16UN$cow{`>|9ZXsFjh{m69&f&-M5D(q4Ytv7N;-0rcy7 ze$V&`&}b3fh4Y=S(tV>J5Y6&oINF@0w;Bl-=~lg{{oWvO4Q~Ds+dBM!oMGXgS~1H5 z{sKExQIQMjI_lKFP_@)w!&FAt`<_`GrR*DBrQdhjXO>8F7+6M85>AC8jMhACJm!$G z(skAlJ+|fuJHSl5K>T9fnr?D6db56SBBpqN%;=e^Caou4x2;AI>U7}&8-=AREBhDI zqKn=zLn#w`;NUvB1^+a^1u;iJn5uiG3&ytIGa_W&8TFce+yOp!ymlUU90+L~bLo+B zk-znxB;kdAQ3FYJvTZE=_*6N{L=<((;4N%pbNdhF#7D5YJxrf=bmgmU z*`I>@&pS<7$)|Ugro+pZyOro;VZdmNiKKeHK~XHL0IboF#qHUTwu_u~T0)e$msdci z3}Nh#FOvP(`}u_BOos611NQJi>roJDB`$drl~3O&&8l5!+3JuHIpE` zp})qj=fUTjc@M3(-W4ZzR3*|if-bzvIf^=##iOP(*jwgau}N5=FW+U@;}FYswzFZi z>#2Z?7Mt1W439hr`<4`Y0|vv?B=BEnxu9Lg42wP!C?m@l1oWFk6{R47KxtM_m?KoN z@}zm;{T7VixQ&404YViYOd_~t<9Be#jTeHAu1UMCzt?-FZdD3CljStwKY2hak3`ES3pI8k>iBw`yxIoElLgDN%|a=NfqBq;wNmFc z6TZ81!`I7>67v5r_SSJxZ&AOn2L(h@C6p9Fq~p+yq;z)*0@5HQEg+yEpp6z7ZAfVw)Bc$y;C`xm9{DoAki;dHhciC| z^4^1eKKB_9SIMhmr8%aw@AC^*=9>LF#R^IFKXTMY`Ndb`C&Vz_SEt%9NedvROrE7s zH{8D6V})$TaMFPZ5PFuhJ9iwT8_UkpWxL4<5Hf3HIDM;+$r;bQzC`_SSvQ`IEB$9H zaoW@ut!E}^gFFOLSNZXghzzkM&7B{F*hUV0|MuZS%7N>sAoiU*&-XTv#TvKINPxw| zF6SK2D>O4{Le20b_7LJor!jZSFW{uVX-ZPT}9j{qUw1C2kuFolX|sW z9{%R5UlTZ zS)9*_%TIW{W#mmM+4J-iH%fF<-jSKkpG3t_x;**|`7BJ&=9^Z*=~rhxNrn-6qpH8# z86P$3N4@bkR~Xy1I!it5){0-VoDXA1E<603L9m{Py}-5=JfW44z_c^U+L#~g_Bwukw3?G}F$+R z-ILEQ6X|1~d)_t0au?sxnCbwP$<+*c#1;r8bFF%1D>(jI`OO=&N*@Jt;*!&~y7rdx zArUP78@|C8Ei+cVDt^Rjah{*xun zQ#XsmmmCFeDI~w~ zaOjyhAF8=@%3`esk#6W$vapBe)9a8bZ!iz9{fZgt9pg! z;IhL)tk@=sAb%{2^FT%1+#k!$pyqVuqBgOnIPLN!k6WPn*WsjrRhzk7ELLl^OO6=x zxgFw}-6Ps<=M&8h(tN285M9&wVNuq^TH#J-v)m|&&{2OQn~{BaEcM5{6A2JWQ$44^ z*q@`}Q;FFW*iTDPKI0YPX9*Pc&q1qP&(DkH#TC0s9xmHq*OY;8L@dD zD7ffzYi_enZbWe2alEi6TU)oE%-O0r1>o`pbn)+e4b0^Y=Exmf@joAZFB-OK&^RaZ zOhKQdjQnwuojnG^S^IbAo|py`7UZ2;j@UnDQ=Wlj@|;DXX_0N&zo0wZSMu+F0NXbM z>_m_zHLML(R^WKIm~Zw5INF|)D_@x^*MiTdL%0q$a`%_Mk(U%+yl zpGG+6rXtD2rns^0VWf$`xO|S9U~W$RJHiPd!Pikdsvgc?JcJGW`la%1?ohP5RJOxw zxuU-;iDriSZtcsm#F~9YS=sMtw@ry<5OJ2*x5Qgg0)aJ#uu*J3#@jd!H+mfGAkR4N zZ!)dtUZ+7+Fi{u;s@Y$^4j+jz{AD_+Zg`p_KvFe@T4X%WBO1|B66CM%pxYs2%z_&N zCDeZyLi!~CF@)agRWz9$_>cF~%wG6F8RJegy;;GuslVbe^;OfS= zm@{1(mc!pu{?cDydj-t$MzAX8U(FFl*tO+QAK&&K6J`b$7RAo^^W-MXdrnPW`40r= z<{pau+EGONWJ3kp;#Yj6Ug()1a4`4q$$x%cP_WIu_KlK#So!YJi`<0EOm%lpz>$2AF4+}h0Ei^eWq@Ar7*n2E~veJc%+ zI%#lKNCU6@(?ab*`zr;*XYY2*y3=Pee*Z$^J4&UzRQ!6l)^Zoh(zC%eHOGRA5AN=Q zOqi!XstlBr%ulqbOQIp^<2ZzH>5XV5v>f<#_G2zjg~eNZBGK9XoaY%^kg| z{>~3;=_QH4^h{vl0`~}F8%t>9{OH&%P9GYt;%VvL%-{<%NV#+N5tqpF5gxjXezn*e z4H}+^V;40?rEpF3WnZ}e_G-F#S=AkrbdEXrJ<*1a}gE zDaaMFS?UB;>~D>l+J9Fba;j{$iiaX|R8eqm|32lTcFoY6DSw9+H9ve07r#4 z7x3U9w$Bz7*n6VcHj8OzfCHi~to>@(%umgAV|S!l`|z+@`>cTK<*YWjN)Y>hS`*yD zdICA1jOL$8O~;o8s>F3Wz(zIgVVQGYXS)F)182p?Wa0q9v&JP_$gfE{8V9k;l8}OavG<};bHRrGu)=VR>IJ?$sl(&9?E|IU(GDW3P<7=J7@(M zm6|2RwGw4oECpo{v(x3$0qetz86YU2vC5im5KdX#0ujXL7a+W_{n?BSw*a~-x ze0zwt0(W+$)#3EVT5Lqnn2%K^)H-aM9KJEBWC1aHVOpI$8u^fc+aO0_;@eZ*Q;13d zU3mwbgoGkbJf6JABc?_Ab45BPnV)_9&>b|AK&t&ZEFpNlj5x6TGTa2YC$m^-w1|GA<{P%a|Zcpv`>QyOj{NLMsEnh_Z!^thbWNqBi~ zOEOL^MiYz$`LQWK7=PS2rbUZLvrwra)V6)_&!Xg`HE&@Oag>jKHa(gs1<}G4g=!h} zm7T2fNh&Q8CBvz{$(>MStqx;EC@@<|m*@FtkI(f#7WBEFsC~70u>_yEp1XTiNxMSX zDcD6xN!9Hu$MTPl@QqEDa@^Lqj*dmyG7Wb&0=hxd1`#@~CeMZne1S4~Ev?v!m3c`; z^GPQwXBC2a?up4nHHi>H1mR{sWY3)!y3>PjmjaTqH3y-tr~-|`_;}*HEC&|KVDlttoRO(4^so&>F$%XNA{9?otc7=dbL2QKkbpBlJ36Gr*oJ@kH9P=|pf$?*Kd zp%{=I{=}54%{Y4}C*k0Nf@!nrkh@#+GEUEP$-_~gAn9-OE!`Y=SJ?vQZC?G7e{_{{ zur(qbgwHgz({v6ej1!B&hnE5^?Kxd&$L0=2`UhV8ad|HNm%~K?A*1}ArjU9IQ8-6c zz^u8rT>WEP-i1ZS+Td-Y%@ zX|w!$|IWb{UIQfhD-HbCDKPx-Ykn}KeD{nY3fT>_EtU69J$*Q9iVf4$qEistI@uQ2AaPnP@Kj^94eGvyhr&R1!1^Q$$}OytFEPzk zpQPzfM8giSRjGl{RzdyGEX;tKbUXY9Q^8F|MQV=Z)Z70El$)r?0aEzUOGVwEMI1$b ztrJ0GZ}KJyi0k!iVzeEN1F@XSR80n3JZCpl)*c`xlB>;!s(1M2RChnDLair%3g+NO zw4}viCC=5De;?4Tln{tTnFC|n(vBgk{v@+-H~7_8VC-A-G7D2*mt*F!9rK@t>XQ8W z`WKTIN+%`e2jK-V=6CMlZB=(qoDAn|L;NPGi2Dq^XCCtVf8&!g1|H`>H>Nw#M+Aoo zO+RX>A>8A=L8l%3`$r@c(*hJKUShxr2K$=!VdBZj2`xSSLDh!44M=T+{ez)GXi4CD z3t+PdTEGd8E3AnIeR_Eewl|j9j*oA+r+1DtB)5TChHmeO4kn7poWQiy? zB(#+_uW$=`f%1r5d)_rYz7u1_5D!c!yN7F3UiQ``67p0>`B21|K&BYQ_^wPDG7q45H zz8(M0J*#xfD7w+$JR|3=k-s6?SI<7MF}hEw>FHITJn?QqUYzQ_L}mAlsrYf>_J0;| zFM#A@8AizEd(ZcTdu)aLQpV@8tOJcCB|RyaS!^OISX$frAJI-hXq3yH>zp=* z3gSj6JbrwybDf`cV?X^UarTv?Ot!9a`wV&`5{BCd+`(Sxx|j1V@{$609J8|G;nV9Rx1Ju9xGpiVz4urpIp=Vzq>@kiuFv7Y z0YinZ(Fde^y1oilpPk-u5Q!Z@q)X;v-om1G2G=5mr-NlW<}X!l-(;TBxzOH;nv2fB z0k1VLLrW9xcZ zcRwZY<~M6~EV#H;XI$CI|Ej>zW#qy}KiELdP zAFUg=IWT$89Y|)1lA2d=e(f38#IaQw!6lkPU85>TA1NAS)MG*LcU;x z@^ziFn-5YS${#V9zK660LhTUDN!J6sB(6sth$7 zyy?U@EKFlI-8S6wyx5fWMrmjKVqar3N(3sa^0y^rxe_{GF{pi>t1QPY25Pkr zovbDm)qSs(UQKXL1a&|P=nAVJu00}B$j?W{109FnQ_F95W4U3m%z$rrI#W&L%+ZXC zcQoUyf4DZ-I@j~JAEMuBa*$jEs=$vtK_y8CrKYv{>u_;#*K)Fe4rH2Wb|`8s;^f`* zjNr})tV_OC{(Hg|d!jOk!%#^0iH^0B8C3GQ$MPQAiw~m(+NOs$jsc8LQ~E8wWbe2H z#!NsozQt5|N)w_*@<#hKM!;raopq?8$np0X$6ofaY_Lh7LYA1A*r?LaZr3jIRnMcB z#fw~>!dA+JtDfGS#bXJ*_|?Rg(|T2(h|;M}i45<)Gds>%XOS&ho|sthXlj>1-$HN( zq2;_IWYo~kGHvww_d~&)v)M^r7n-5`N70^VyAq%ny%t5gC-jg2l#h+3Y}hZAaYC9a z{mTQIu_SQ0RyT16-{&5mLxOHw zU58$6ft{hXzi)WVge?FjK+$iDgQ6j9uYMR@mTn)%u;yoU-;IWFO3_i@kUkBdm_C2V z-&i&?=xmb_#I&EbGOw4)+@ArXb@9T$vqO{Z6YssctwQ>by z6q~Ip_ZWF1mVZ*R8nQT;|7Q;bArES3DEe&E(hO#|)!~m?z=6Uvtf4_&-ZTi8a z(--o97qD92TFb2M$l*V+={fGfc!MZK{NmKtqgTEV(MujU{g7uOdU-3x;xfEeUCniw z5qWU|wdsv!5wU4J$-E4c%Dnk(G)p!v^ZaP4f0E}V6*-yJU(EvISF{-$c4SY=331A_ zF><=-GeOs>^4pLYdC0OYU>#)U2`aImqo4Oq2O&1;+IPHgWYoCMMa3%X8Hbe^(~Zh0 z>wN<99v&%)RGy>TBFDeyW6Yv!D>U%|vDRsPWgxi9+uB4)9FM5Icn!xzE?8JMTi6hj zuSQ1>P~zJ0!^w^OWYCFaIrvbK1o}1wTFsJaf)Z=i@+v6s?8@`?UAQF$*ZWxb=BTCj z=Es+$tSUh$?>5HOhYd9Z*=b&&Kbo|XMSnD2*{7yvGUuAp<;JF6Tw>6RZ`o6>AVpLp z_i|CG0G`AF^7|!liOp{YVwMz9;S;@=op7mRr_k^b96u5_Yk&Qs(z&vAQ7r zanQAvj`s@ZmCYp^Dk{ZHRS3o4n)5q~-9=AaB13&y5PH8AHIH4<(4ePvy9Iy!XwVj) z2#FgVc{!yt5bJ0s{PSmFJY3wL+RTjwXI_Y9&olPe+H!*l04~xcHP!fc(9LhOIpc^Q zueH(M!eSIJA&2d%oxRL9kyvMECmlI?%bbs-WX`e;;xk*|z+e=E?R{%ELEqM`GTCDM zkletWeNP;`jLU(`Hsj>b-fM*-x(vms{!AA>r;Cxs@ev@y|-nea)6nJ;2GDzz{2o>b5(DP1#I99cT@AY zbAIpm&`UF3J%gAY&J=*I+yDn8fe|DYd%$D`wFOwK+rsS;npYHM3#w5w3c>rCiBu6~ z_V7MWsbrEaNhwDXua*ijlN3W8R-bLZ8F*EOBKrj{u^}CqF5u?5Tq3w& zstsjDe0D_vRjKnh6!2qM6KE^nsIZzGm_z&ovJ~rQ7v992zg_$O&0vRU^OnY{q@C|f=3;$dtaCUwT<>dHS$k&};P_YE9#kz)ne4ay@ruvbIWZ}=vGEBFEZ7x$fM)!!>57B86NOp*cWq4`M?}qsQtpy%Xne%SrsmlahHVCo0t%@A@pmhQd~OnG=6s6YO8&m{PBe|Qy_e!UQ6M3-U#52`TV*}0SC=(PNDNAF?Q5Er$@%4i*2j; z0(vPP@oEq8?2Fjf@Wb8pcYu9+ zrP-u*Od6qxrrsHjHNP|}9F=aedU^I7cRi`9UrjvKhOgq|qytel`VLfRzY6(mE1x9e zqN}}A(!#UYf12}&wDf6|#~@X&=O$yqR8v`OCg;#>L*D>HQ9q<3>>?qoPDOv3Qxug` zUOAO}b?JhzVwAAV&uu!ak8@ncJK5vw!SZzx$EWCXCzP>9nhX#O-v>J`1IM}l8~Vkc zKV;D&xDWDSWfc0XsWM^p+eqe|{uqM@mU`C8diUCZ_G4YArrG$5(3ic;@Z}ogn)0WH zeY}#nW+x?0{7KQ#*=c>G%Qg}iZeIjVO!%Yy&1qA-LmHh^)t=jobYnBAY@}bV$9}YV z;hiwesFmgt2Q}ZCrnj1@R+$sDOd}18?z)MAazJaDyA|M@p$*O?q)a0ma`$)j~ z{}0^ak%rZ{h*5v(RxqyjV5hd~U?mV3o<{mj{CVw(y-LgyOnNNB*zQr;DMqU=c8eAd z=Yo!gbJgbt-y8TLT(h5Xs|b#5sXy*}qNix3)Bc^aUQZ^H?Z1Y&FO6F^ny8Bmw0oQ? z9~0)5s9 z$XGF-m6)^eX64mC)<|&fYw3O}t3F0f2p*t=w~Ost4vE z%&Yqy&W-!ras=_iBCUY8E2JTFT#e3be{aCi(PME2Mr92rq0T zC7X^)^Wx_Z#2O$6q+)8FJ16eA5Yq9_yEp|dRXOAhm|54ZMETAdfbHb*Wb~slgIt#lWV=>3hQKO(*TS^Kcgux8o|Iz;nlo9Eng3Fo*eC?O^Vi^zMB6nmw zBB4sV%x@!9G@WH8K7pt_(l22R+bKWn59R9aOm?GFM*j7%vHu0YVq~iLS*ci!s1nz- zHK@{ZU=oQY$MJ3kD)f_tyAk_LT@++qr=hO)C(5GJSN+{&EbOBKXf=xY&?G0$5`3*0 z@kNjOp8vFuw0ZP1h{I-pXVtzvgRU%?JIQhK1)1qEPXXGh8`>lOs-5cldg}RD9hY zdQ?*xI$rV}dg>c5@o#mD7=sw#+#^3fKU!*P5GHlkKDm5=kC*d>Z1l#X5vi!hrWu*< zUDU`d53s*mZ<@NER3ue6LB)GrH`zT(D!flI_{E_&pdDWBZkVKYrIVJI3i1Lc!56c! zS@E)T>|T4?wO(yTv3K$lql-gPu+|G)wVMVuZTg2Y<7G$pH5SDwI~ms97gir9w9i4v5!-ba<#UfE`#Q! z9P)5}2N=cm@o$}|UV>JMDkByP&>AL<990WqR^t84wRf9|kWc$nv=z&q8=mt5-OS3G z!a68$-Tk#~PSa*gxkO*Wq)(%7A0fMz z`r$hiZ!`Tn&tg1P z>@Eb4r%_tDg3q;_gV-%E(d%V3Pvk2hxPX#ci2=}fc=FzA|JZIPnT?}FC-GI9rTG`lCRB2_0?Jc<$FRaAoT? zp|_6+GCADft3#%mYnAPY+xDs0penwnMACoTHX;2w+x!5Y>yeLu`BZ*TAE|b_@+Gun z_C#HN=feieD)T2Z!~0Ac2^gT0e&C zT(`O@Ahhj-SP>9;?4sT7I{&LU(=?a}H{3W#fkFH(lO4r@Z) z5co0NBYFs`^aFjJk?Hv<(io;`((T-){BGC!p`)OKv#(G`S8l&v0zyE`k!sxteRJdT5>g}TKT%ClaU~i4vliE-@}n@ zX}PFLpI7ksm3TR>u854vn4^LPpUYd@m>V9&YWPlJg5xE$rPpw_+^_eOk8?x@CrQIe z?De>C3%L|!n;{v?dwvrWk?aXff5}l)>G6OKXIiT{g@Sw^lCR|osrRc8UPiUZpEU?m z@GYo#o+>0vk1*|l^Xv*Tkr~az1xhZ;fWSiF_eQ97!|6sI$YRN0S8`gDi;1=ES_O|#nF7$UK$0?IR;t0`1Q({srr@Tj7aIDF^`C9^r) zQc_Sz&PsHZGEH>J1g|q-P9R_4W1yA5{C8QkZEWKnI7mc3i>rt-gb$9|by`~fr^jzO z;El!>g+DOkjP%)9EdS;7gGKl7=?a0vl0Oi0rp|eceM~1Uia}coxEt~CG^M|xJ7EXd z-ZebR@E6v7No`x7ZiV#8$| zcywHh{#Tz`B9bYEN}Ih3%75Aw0mopmjk(n%!ZEmM(r3~D(uP3LBl>&wA{HhwmjZC1 z*05{kLtFUsA00Czdn**w-{3W&$0GspgFooBdB)J(Uj*b)vm3VEv?$PUa;gLYj4ZeB zH4^%sCmADkU;omr)sp^3PF|U{NB>*}#Sj?hY~X&tZ`!rvpc-k~U_y5DP$Ci3a8S>Z z!H+5SO>{y8c095{Q2?)Am_lbU(1282NU~@FV1>+(5c-xJ-d3m=#~wK#A_6y^KB)`%P-`yd@iLG_=$T@-*TfPIoadi@d+mS2EaZh+Qadk#oCmeG?K-OQy}QX zZ5s!J3j!k@P%vUX>=H7wY&?vNeO_i6pzNzQt4Ys5oK53;Q+gPUaP%Q4DQ?zuepFV; zsB0kHLpl64w!Z2Z)A4=tZdfJFJNrx9O6<(^^Y~883f=78W=HMpi#-qq|JMN0GWf)n zq@fZspnxZEw&zS)*Y)bZVcz`sfE*v@#KRc|7ZBliFi!->D;o6cf;s1WiruowK%4H< z!`>>Q_hylimYujNeczm5ZrMUUou0W*3T%7FJ6mT+aoQhXz5=aA4%5|B?c`=3QO%$` zEg^U5{k2Q&fBOg3DA2J!QnGJD0e{a8H&`VYpGKI*{C>3eL|bu@w-$LqZ3r+v8`}`Q zA~s=8W&;KI2g$t7zBSE-nf-(GQD3};^~-0h<+AnpwQ_Oe)7v5u9sh}_PU|2-9Ez{t z8~&hj1Z0^Zm`;YLd05lLTw&-E(NU!W)PI?)q_K+rWerdfq&8Xs4?vs#a&wXb_!--Xxr1Kzv5b)b?(LBb1lNDB3 zj5D>G{3-CdDM`t&R3h=zSS*q}V?VW|XQ#)cIqzIXYj2gicC*%=Ru`Hl4(jNJ)@k+2 zXl`#J!kl3cK|WMiv+ zaWQ_>nA45 z3mZ4aX3mqi>>NEjHaX0Q$k5>PrNsb6HF!aI_Azs2N+6QAn6EAJcY>{--vms}7FB7+ zxls~r%zUi$hb-8PGI#CYl|BWvdEwz+0J)NsmM$Ch39?`l8cVFuxb(0}bb>CqDycGg zgmYLil=1}PSsfm-=N3W2Htr!vm=?sJ3jjAvQebhU>fbgIjUBH#MsMdP-QrH@SJzur z`H0ldGGxy>#jBrW=Hx{gUq%dE(U2{aHdvyp*+k%ScNf~F{j*ATXtalPR5C}_rF4Mo zD;2V$m$(FXCfA!qJjberIe9LQcFh+LY}ldm*GCvzHV~S`a){6MTugB2%33nAVZ6m+ zw2;Pc2dE+U;XYOBp^KpiCq6fNh*JvJF_V?Pvd~Rc(c;c{OxwT9aCx?dpM*b_Ed@#k z7(0TawWY|3Q}>mlN5fBux|YotG2bC%)yKZ#=l8h7?jp^}#424)R=r_{WBS1wf&)c< z6E64$C_DodkG0^@wDJvZQ|1UUm-Yef>qzYK{dx`MFLocEUrgD6r*ll=n(!I+cJ7jf z5|X-9_%nFP8dYiQ3RGZK>o5sSiZxBUmQR{gjto}GjQy3SH((6i=Y~^D@_v3X-p<3%^0JiY6 zC}4!CON(3c60&~yjgnDpT#Hm+qq#U=K60rQ71 z=R6G2obYMzf1ytR0-ZEP(L6gWIJxbq21OLbs_dSOinAcVmY>qM8o>oiIixqBJdx5N(t$j50;{DKrdsI0!G`#&yGJ`GuYSAs!LVlC?oj(3i zqj%>`9ZsLa`yY>pj-tyV#Uwka3;JUqY~UI0AFs#Z(XT7@O9dZbY6$*wX5FGKe<=cV z7)(!7HNhBGQabh5ghizYfK4dAJlxMy#F z4uci`))2s5jQPF$xp@^9V;jA8MtEcdSwT#VqK^~ZOI^u4s}W#~j$o3_Iehq3+cH5S z{tdi`0H5b!?kcmHLA5jZ5YK$h_VjuuTwyEuv<;==+DVw-vOki@QFqy-xL6OBduh19-g0}5}vIThg>7j5*iw89a?&B>^)79^m z;>9<-B)86m?Ltu9YkXZPm&PrJB98-}9Fi&p_5_jbKYU&1tk5B);0SPI>2t?jl$gTvx|o^p}Q zzbA?FjhJdBY%XfGMiGAfw|9_H-vk@_LKQ5>BgdU-8CuAs<~>_N$iCZ0aeQBb;R&5e zT2{7zmL>dT-c_FZwU;LHl@5t&S{Z69r}fvj7TpSwCqR z@j~p{c%J-FkEy^=pm1K1t)GCWNv2%mDVK4q*I+uVJa)r{jmnlKJgPFMF-RMHIfi$d zIZ{E$X_ceab0Q$fi`%0oo$qs&Uu);_}8USAfB2)J=@UYAY12NgBx+CdEN?n2y zJ}LeUfP^XJAJ)rEd0-DZnal}wCG?G|#w;Fe6iuCPPI-B#F8*CKq?sTimV%2MbU0P6 z$8%gSGLq|A8m2^)XLY>ju$-oztA4Kz;Zhj_6qfT_*(ho5QF<|6oKm6YzQ3k$5iK~U z73P)15XY%)ftBcR*tA92>v6$)uKXiZz|FHzt~S4EsI}&$n!Cle*LaE@)?+7u3xx#{^s?-y@nGk%A^(IVOPefrASq6nUoG zEmd6V&2s{zV|1r8+ay-VE8{tIa+Q(?LkoY21;plPmYHZ(8rHmg8Mx>*WR{gPbpeHb zN&rY^R@iF*Wj55ivRc`W+oR@#l(XPfM8gJ-4c0Th!wW}H-^unjB{Y-5j|Q_hX1*%! z*>M0}u@KG|gsMZZ5l>q;ZeWj(zNHpr4~m!V10*}i(Ry-MIF%;t=CiD%!ZhgN zK4%$%VCBEu$1;xO6bsegeJgNkTr&E6mBwaDN|p@j@3}Q3S-cYlW75Ut(PM zsr{tQPZ^u#z>j&l_AU?7RI~p8zODy^Ec&(@;QbRlmu0*eAje$~N7O4`E=yV5_y`cn z2;02cuSWA=;90ARhDth%QQ~mGV&`TjndcAKCiaYfNNJU-FF{~YvS$q|=ZhWIl@eZd z)4(u`eS(+nGmc}rJUjLKkXlCzUAuO?CrwZ87lIV83$;Yrh3I8JxcuE)tPd5=R=Z8h zZ(|u=ba`(#ktB(!NpBlk7dsk-YHF1$A89xpy)EPNu5+Z3;Zlq;OkC z@!6cmv1%wO|5-1+@(cK`G?N$>&KsC;U=XrB-5f0_bM=9)rG@5ae6i~3JFePOx!w65 zA5QYW1^fdw;1Bx-9CA}>;{y$D&bs!!?B)}t86#!VpjueP4S@6e(^DfvAGH69Z_hQ) zChTi`QW>(I_<9GC4WwW2GQX45O$JEKG$m!_f{%u*p6BgaxAZj`gO{dfX9YEq!pr*g zoQ^=&jePJ`E3>at%Ao zP0eK0?Qq*%da4#3AGir*W+l0mtengp$DcV;C4H5!6HuR?%h|8JpCaNyIC7W;_tc~( zk9xPRXC;xcvZ7w#@z~^*TZ}bq7i`d?+-h%59&<0e$ARm}%Q0-DT&ArtAluZr9N3BN z$~a@DGL}RLW11fVwNSBu)?qviG8(qkq0D8QqS5H?;wE3NXER&R-3Pq-uXfz#h=3o}L8K*k z_G>8tl~tKz)v>XOO~npuxtsEsFelPe)or8zkR;Rr>WSig(sNx8C&fwN-7X(qAe#Fr z4ppr!#lwi{)222q&0NV=d!W&!fceiJ=SN`&C&t8>&1kK63SQVvzgi65^<#2Rag@%W zfAdApYg2nJaFuVBdpqrM*1c;EZc(4Pma61vFJdOX2>U1&h<+&y*Dd1OJJD&JaluGS zQPlM^hpD$h8|L@9mI#Bz;{ngu%~fxpWvu`4S?%V>21YuY1#Akzs(r$QBG#FezkT~m z_dGNg1<8E1*6J4=-AKkPyjC}Lid?YLe|6T(mhA{KjoH|T(=xAULk8Vjfl-7 zS`%XnFzPiSO{4%Z2LYm#DGhUUcJ`otl{NNk(q|&)vLcv%@bp>Sit7O<<8C{1J5x*7 zPRefM6H1$vWSU&WzwtvEd1#p}$PTj(4G4S7Cztn~I}@sAhhvik{xx)7Oj3VUWjv=+7S>eanMgnN8@u*m=gwK+hHg5!?;Z+wI=~gn zA@+USvirRqMQw`xJh}X0BW5yLpqsC8=f}PL^1cWH~lo76|Bl)50pK0 z=bif$EK}6s#-Y#0IA-Cgkg$`LbgX#B8q`U!>P9kU;i(ZUZj=q9hUVuz#KW$EA{0?Y z{PpZlDiFQXaa;s-`(vHB%oOU!(~UCQ6s`sz8kX@7*ED6nvfQoK+xJ~N@(i33OW1D+ z(f&eR2i`!BOZQpDLlMZZ%b8S0Th-%_z5WpvVPUpkLv6WmZ+-CCJkOc z$fi-{418?>As1nFTN%KC_to`+zr}lFC|WKwc2s1wAYyOqKKxu>KfcSQ5}j${3UT18 z^+SqjPiz{HUUg~TTxIX^a%@0jd5a*!xA8Fr zIss27IO;g|o_$4?_?_ub>(fmGED0zHI})DOo}N_}c%fa#cvV4xop{I2aZJ{*)qEiJ z7HNM0JLIbiYhZ^IaBC1E0~Uv1R6<@iuyido>=i6z!eEOl*9z=+T4U!KN%3!Ar96P! z-ppvA(Ew~m)Z}+3FdD=abkAL(H;01U0oAqF7MVmLw}6a zY)ebV#YPyM(pl{9;ViN<|}mA(|gqa zFe_#rHLmvx7t{WRKR@_kHN?iE&&a(qAI>gBT-w)zcevh5t_B9gt708y{bC;1(jMF1 z`}izrO2NcYr09omG>gDLgOVZz-0o6iTk5y^B9W<`%-pR_jVBV|{(kS2@5wJleyu}d zen4#1{@!V1(kJ$_eU|rntBf3T7J|#a1x@oSG-C1mq)ZdfuN2>e_+R`IK+QkF-=8Y8 z@|$ZR*y6Qta$612Rr~w3!7_rfy=V8)@8=Qa{h67$7x&uTExgFWM76U!9H{+TM^ zY+=9HkeQ-9?8dp`a784eMUk=>2(rrrxxz#qq*JCWCx#V6w)i01>^$e076g_Uo~)N| zd(VeT15nllgqdLj=Fn6SL<;!J%m;8VK$XL(@HFZ}O51y{|MQtXQh>mJKcli;^Zn0f zUV!nw_;+t+I9&8Xcj@7akH$ZQ@ztjR%_*q=p4$TkqyR>?mLWK6zgpPAO=6z^c6Nsg zcS*MR&;rXE^K^K7e`A%kCv<&v{2AuZxDMdJfBBjZ#LFQzAzgZYAQP?9!KruKDp=1S z^U+?c6AD_x=Qq$5QftiI)_!BewmbkVq0^D01>fQ|>wT9m%rXpt&qS!O@9qhusILh* zzL3ijd@A@!5yl))Dm{HG~sYPzi`g0SPfT2VBXa>M5o^}CkQQ^!lI4vAxMA+UPk z7eZrAu=;ny3MzZxW(2o0%SlBLJ42y0b!m6XBwN7>sRYBDN-TN+sVm`uW}beSG1?7v*EU zTmnI!=COjq&t_ur3W{pZDoh3F8G6^tvmb+vyw-(^C4Ha6!J_=wywN$aZu~-0bL;#d zZ_Lquupm?O?ZAC{1>IkBz4o{A@xYp$X8uRLX?@Ga)wFw*4pT`qq^y!b4RfA&MZ=*B zNuRz}qM{K5<`D<3YR&+a=-0k30e<>Cc=rj>#tC=A>LKe~4byOqSBeo2CeK{x*|hc8 znlt0DMPuCAxaIS|o~%-DaD1XmEE}+UpS0qDppDlLy{}6b+T)32NwTw}YI3*C|L)x3 z4p;H>K)QRSgT0h-v1(7=gU3Lx8d=}K3i{#&^-NKen7JTLFv>AA&wN61b=VGNZpYT% zt%f{a=uK1EY1Uq$eI*g#N+*XP4(FOHDBoDo?7aa*gD=n325Y=;_Llnd4{P9tPrP?; zRswAO_g8BYQ7jtYgdV;4V>k@q`R1_UKR&t_(d_*wBPRyM@rqe6V}Lb^E3;y5ToJQ@ z1`=x2n@kfz2n&Kq2;E0QrIP#Oi)4E5>v#Xv$1U*1zxq(QfhF^2AI;f(Kj(dsP&?%R z=*Iv8PAFgB-qvD3yD4dqD>im>G@r|Wz9P3F$?o?>X2t@|GS!vsRf11ocQ;tC+y7eo zK0$4t;ZEB3-v{!(b$U9!IVDcl-c8&08-uYjD>iEPn`C1e zJYOAN4-ijdIWRDzcT_IBhr`VGn?M&${6q*^`C7>Zv-ayfS9p(&d5)PJWbEp=KCQD0 zW_uQW-0oMux0IIs(-lxtXSG9}=S3}Rd32^K)^EC{dge86AST2eG~<&~Eod{jT4miW zUh;9y$}3a7OfU{;hMSh1=ofVY+_=Mb6c4+`v66wT&3IAY>0h4yKa{6H;#$?sZTX{z1wzvCZB}dzmII#9!1gF=}5L;Eow^{cay6ynH>tq>TH( zU{Cxu&dvK&()K(Ex@cA^`TVSn$0mbqjrFdEtIPbL3vbrKMv%&Ho~a=PMC%3yQ7sVE zK5yH70{hOxhqlih8mshph>lwCwX@@g>3U6jiL09ZVzV0NpowNanm)Mh3s=`Y#$o)! zrn}&bXKPb6?E|s~H6#aK4%RR1_)2_&V^-GWK@FX?!@mw!0U3yrQWR)1C|Dccw|^S* zFa69(Z`87%=zIIN4lp*=rx|HUfz4^vSUnTEa55vVSXHC58}ApANA&v$RLO0VnN%&! zu}Te}#pmt`oThLmAjDX*)D0~9Tyxpp+yb8LN$9%RuYD1UoCfX|q=0tZq_hDGh+|e_Xm`xf@t7%&C62f%NvM3moqLYQL((Hha;t@HCD}ju@#>K8tGp@9Jh(25p5Sy%KkB@2gvd_uqc1A2A%225xOaDn5a;RX?`a4=hme^UwJRc z!#R6!%DO=FZdS=`X2W+s%>UKatVoZbH>znP1-| zO~LCYKqU66RJw%&)Z>qvCW|tIt~eg|y*zl0=nW(D#Ba=2RcgOZ0@VoqG_FvCjM)5# zIW03SVbrVhDD%=B_<(uU%-CFwYbiy<$t@$o_n!}31|Gl*1Z5}Xpb`JAxlg-1|Kw^u zIy#N1Db=}8;Q3AeUvpO)*3`L#xoy3)rHYmUN`UC2h*}gBfmk54qIj)UR4!o)q{=3; z6%hhtleQK?Ah#}{prMv3$dU*WQh^Wd zH0XQ-D1|QZak2Kd>(qo#!R?;L316ooK}X!670jUN@O!JK=I2=~Q`lESd-Wwfu1GiP zBdZ1vKhP%*T^Z1I13N~&qfb5h>0tV*#R5*(QRZ9zwl(!ntp!awtHWT|NxrVT!L6No zXRg7QCVyd(zxy=9qm4LBA|4Nqh>Q#c%MysEFU38Z${VeT@==)@yx;_*Crww`zzDPe z7_07u&D1k;H*(|3#ZT8Lyuhk`{ttt*XRn&-Z2w~CG7@_#9|b3^5%7+60H2@trH+W7 z?*>cYn68m;>USPR6m&;m^yQtth9UkA)O8-baB#d(&-j)qaDS`MAENLlszt4~Uztt- zmPIt$W)_%C%n1?}drf86dx5FbR6QxSMn|A7wcCjOJ`yy@dJ6sdKY6v>J(5%1)cjU{ z|17OFcZv6;9BDd5d!Rt9Kc#Wyi|!+#0oZsBRVrhTJFc#5VDN51rf&&b0vEAHftwlQ z`qbH`8>1>}3VV>Z3B}>ygSR_wGGsdfQ}N6RMO>7(Zc`4aMAjs);UJ)VXv_XF!)l8y zW05Evi05jQF+urWizE)iQdE?bte!^C-8K?`qPCuf2_mTbmKQ=*VXqr>-2_E)as zW*f#e+V$Xs`NCFX+<_j|(t1?^eKEGT8%i8et000y=15bXwp}5lz>`n8EtQY7$}Pxt zrCB)McR8Md*Fpl7s-sKO_f8Vx>^@bDrHrJtq@>Obo?mJ%4;_3gYBl5~UdGC+X9Yln z>eoEBAW|z5z(lbwYzZ>$_`O8+_=OrpU&$++lvV^F-8A0tPbluUW*u`+@cV;=EXb*B$5Wis?;BfGy{vH*d=H7s=E!+|)6I7@3xw>a z9#34k>Sx-IDX`>l3@P0$EeI>&*fJR@+?Ba=-P~DWu?Pi$0P_RNapGJiY65VPrgsxe z;Ub8ZKH^ZZxU=OsohM2Ln9UcCS=R+;E6diKmhndo92sFF3tqbbK?U4(#yupju1cW;xeB^8daesPWUz&?k_lXs?UH6}zj zx7K-nIJS%mLH=2`^rD2G(zI&|X(g8w2QjstV80?t{2K=pNDmXTlUF}$`?x(w|$%`J(q>{Y!|uAt{;fo1o)?fWpZ;rkPNY=z|> z>VPhBEK5y}m9E^DX>eReh;Y7Saub?6nFZZ&ON<$ouuI}GTVK7Bx02k6t=oxi@VPoz zNM9QM2rl5IPI8~Tu$UDrQ(SEUo{DQ)q?rqr^0|gWGDPdP@7LFIm?){2m}Ka7fzO96 zJk;(cEBP;_kNxP|0M$w3_pSapw9=s68o|?&l@m1W{$vSm7d}Bn6D%n32O6mgsivD= z6&V*$;ZNOzsJxR&SG>7aZV!Beoo>dJ*k4>uklyf{%On!!WmTF;VDll=5|g^r4^j9QF-I;gus{J>5~=t8#?GodC&E zh6x+0c>|N}Ey}^*XKBJ;Vs1BoVauF_s|BN}%|?PdB{5khA#y+|e~PlE_|qj5Osh`{ zQ3|P&@2GX=%6kb;q-6n`mBdyL!WyY(!&5C)hT6SwHN@lEbyVsl%hbik(hegUQ=OO3 zYmi{spX4!;*_R zg)*6JzpE<*JXRa!tpiwJ5oNs|3_8;R4DO6`Euc<&A}5^2Yhw%F0xMf1%ZamkmG*~b z{T*aQITyagWNvQ}+g}1xa>ETdUd43%S+YKcUFe;5;Mk~6Dh+P+2fpl!aSn}$*lC^i z`oZuH-RI9es$XX3;YY%H~vYxZ1kLlre59jR-+tLDn2F9ffur6KeNtekN@Q-w}{Y10#@n_&Q z=^#dDJ;<=O0Pja4APJf!#Ao`|g2T5Q&a;_7^KeyhlXbX5ExA^%1t5w0W1NG$Z{Xil zu>%dm6v)rOC|+Ruk=liGLuJ0=PW{-yot+!!=n5_Z{{*~q4T1m9)%75-iw=K32dd^9 zRyJ)jvRL46Q?1Om7_;9scH4-NzljRoQP`;|A?8{3>YGqD-QBzL z94oQw68S(c9{o}sN`t>B3n@d`OTen;&PL_qqT*)8lhwXIBa9$JqMI2Xj*SS~UM(ym z`137LVE%Zzr*kzy9bTL`)lv$a@uw1y5d_+q6T83J%og3uDjVuhoT4j%bN&~p4q9>g z^l7Tr3?YWrFCwUc%iMrFy(MsU%+QHp%ZiVA9!4^JTKRb7&6!?A@_o0kwqx*oLU3(N bfSPc@#r@G1M8(u9myRDjb%cEQ>u>)Hf3A3M literal 0 HcmV?d00001 diff --git a/docs/source/images/topics/xcom_if.png b/docs/source/images/topics/xcom_if.png new file mode 100644 index 0000000000000000000000000000000000000000..39805fe320807601d150cb94bb317847072108cc GIT binary patch literal 17449 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