{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "42d687fa",
      "metadata": {},
      "source": [
        "### License\n",
        "Copyright (C) 2021-2022, Xilinx, Inc.\n",
        "<br>\n",
        "Copyright (C) 2022-2024, Advanced Micro Devices, Inc.\n",
        "<p>\n",
        "Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "you may not use this file except in compliance with the License.\n",
        "<p>\n",
        "You may obtain a copy of the License at <a href=\"http://www.apache.org/licenses/LICENSE-2.0\"?>http://www.apache.org/licenses/LICENSE-2.0</a><br><br>\n",
        "Unless required by applicable law or agreed to in writing, software\n",
        "distributed under the License is distributed on an \"AS IS\" BASIS, \n",
        "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "See the License for the specific language governing permissions and\n",
        "limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9f137b92",
      "metadata": {},
      "source": [
        "# ChipScoPy ILA Monitor Status Example\n",
        "\n",
        "\n",
        "<img src=\"../img/api_overview.png\" width=\"500\" align=\"left\">"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "61354ba2",
      "metadata": {},
      "source": [
        "## Description\n",
        "An advanced example showing how to monitor the ILA capture status, by running the function ILA.monitor_status(), in asynchroneous mode.\n",
        "\n",
        "By calling ChipScoPy ILA API function **monitor_status()**, in asynchronous mode we can do the following:\n",
        "- Get periodic updates of ILA core capture status.\n",
        "- Call other ChipScoPy API functions, while monitoring the ILA status.\n",
        "- Cancel the status monitor early.\n",
        "\n",
        "\n",
        "## Requirements\n",
        "- Local or remote Xilinx Versal board, such as a VCK190\n",
        "- Xilinx hw_server 2024.1 installed and running\n",
        "- Xilinx cs_server 2024.1 installed and running\n",
        "- Python 3.8 or greater installed\n",
        "- ChipScoPy 2024.1 installed\n",
        "- Jupyter notebook support installed - Please do so, using the command `pip install chipscopy[jupyter]`"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3652ccef",
      "metadata": {},
      "source": [
        "# Overview\n",
        "### Function monitor_status() Documentation\n",
        "    A. Function monitor_status()\n",
        "    B. Calling monitor_status() in Synchronous Mode\n",
        "    C. Calling monitor_status() in Asynchronous Mode\n",
        "    D. Future Object\n",
        "    E. Progress Function\n",
        "    F. ILAStatus Class\n",
        "    G. ILAState Enum Values\n",
        "### Example Steps\n",
        "    1.  Initialization: Imports and File Paths\n",
        "    2.  Create a session and connect to the hw_server and cs_server\n",
        "    3.  Program the Device\n",
        "    4.  Discover Debug Cores\n",
        "    5.  VIO Control and ILA Capture\n",
        "    6.  Configure the counter using VIO output probes\n",
        "    7.  Define Status Progress Function\n",
        "    8.  Arm ILA to Trigger on VIO Up/Down virtual switch\n",
        "    9.  Start Status Monitor\n",
        "    10. Toggle Counter Direction - Monitor Status\n",
        "    11. Status Monitor Completes\n",
        "    12. Upload and Print Data\n",
        "--------------------"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f03109c7",
      "metadata": {},
      "source": [
        "## A. Function monitor_status()\n",
        "\n",
        "    def monitor_status(\n",
        "       self, max_wait_minutes: float = None, progress=None, done: request.DoneFutureCallback = None\n",
        "    ) -> ILAStatus or request.CsFutureRequestSync:\n",
        "\n",
        "This function monitors ILA capture status and waits until all data has been captured, or until timeout\n",
        "or the function is cancelled.\n",
        "Call this function after arming the ILA and before uploading the waveform.\n",
        "The command operates in synchronous mode if *done* argument has default value *None* .\n",
        "\n",
        "\n",
        "Args:\n",
        "-  **max_wait_minutes** (float): Max time in minutes for status monitor. If *None*, status monitor never times out.\n",
        "-  **progress**(progress_fn) : See Asynchronous Mode, below. This function runs in the TCF Event Thread.\n",
        "-  **done**(request.DoneFutureCallback): Done callback. This function runs in the TCF Event Thread.\n",
        "\n",
        "Returns:\n",
        "- ILAStatus when called synchronously.\n",
        "- \"future object\" when called asynchronously."
      ]
    },
    {
      "cell_type": "markdown",
      "id": "94e48b2b",
      "metadata": {},
      "source": [
        "## B. Calling monitor_status() in Synchronous Mode\n",
        "- Typical mode when using this function. It is not covered in this example.\n",
        "- Function waits until all data has been captured in the ILA core, or timeout.\n",
        "- Use default argument value *None* for both arguments *progress* and *done* .\n",
        "- Returns an ILAStatus object."
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e3e2a62c",
      "metadata": {},
      "source": [
        "## C. Calling monitor_status() in Asynchronous Mode\n",
        "\n",
        "- This mode is useful for reporting the capture status to stdout or a GUI.\n",
        "- Function does not block. The main thread continues with the next statement.\n",
        "- Returns a *future* object, which represents the monitor.\n",
        "- A blocking function should be called later on the *future* object, in order to let the calling thread wait until the status monitor has completed.\n",
        "- Asynchronous Mode is selected, by specifying a *done* function, which is called after the function has completed.\n",
        "- If no user defined callback is needed, set *done* argument to dummy function *chipscopy.null_callback*, to enable asynchronous mode."
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d9938184",
      "metadata": {},
      "source": [
        "## D. Future Object\n",
        "\n",
        "When the *monitor_status* function is called in asynchronous mode, it will return a *future* object.\n",
        "The *future* object has blocking attributes and functions, which will block the current thread until\n",
        "the status monitor has completed.\n",
        "\n",
        "###  Blocking Attributes\n",
        "\n",
        "- *future.result* - Returns *None* or *ILAStatus*. *ILAStatus* object if capture did complete successfully, without timeout.\n",
        "- *future.error* - Returns *None* or *Exception*. *None* if no error otherwise an exception object, e.g. timeout exception.\n",
        "\n",
        "### Non-blocking Attribute\n",
        "\n",
        "- *future.progress* - Returns *None* or *ILAStatus*. Read this attribute in the *progress function*, to get the ILA capture status.\n",
        "\n",
        "### Blocking Function\n",
        "\n",
        "- *future.wait(timeout=None)* - *None* value means wait until status monitor completes. Argument *timeout* is in seconds.\n",
        "\n",
        "### Non-blocking Function\n",
        "\n",
        "- *future.cancel()*  - Cancels the status monitor. An exception will be raised in the thread, which called the function *ILA.monitor_status*."
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b04e278d",
      "metadata": {},
      "source": [
        "## E. Progress Function\n",
        "\n",
        "- User-defined function which takes one argument *future*.\n",
        "- Useful for reporting ILA capture status.\n",
        "- The *progress function* is only called when the ILA capture status changes.\n",
        "- The *progress function* is called in the TCF Event Thread. The *progress function* must not call any ChipScoPy API function, which interacts with the cs_server or the device.\n",
        "\n",
        ">    Example:\n",
        ">\n",
        ">        def monitor_status_done(future):\n",
        ">            if not future.error:\n",
        ">                # future.result holds an ILAStatus object.\n",
        ">                print_status(future.progress)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f914531d",
      "metadata": {},
      "source": [
        "## F. ILAStatus Class\n",
        "\n",
        "The following data attributes are available to read, when monitoring the ILA capture status.\n",
        "\n",
        "| Attributes                  | TYPE     | Description                                                 |\n",
        "|:--------------------------- |:-------- |:----------------------------------------------------------- |\n",
        "| capture_state:              | ILAState | Capture state. See below.                                   |\n",
        "| is_armed                    | bool     | Trigger is armed.                                           |\n",
        "| is_full                     | bool     | Data buffer is full.                                        |\n",
        "| samples_captured            | int      | Number of samples captured in current data window.          |\n",
        "| windows_captured            | int      | Number of fully captured data windows.                      |\n",
        "| samples_requested           | int      | Requested number of samples per window, when was ILA armed. |\n",
        "| windows_requested           | int      | Requested number of windows, when ILA was armed.            |\n",
        "| trigger_position_requested  | int      | Requested trigger position, when ILA was armed.             |"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d1090333",
      "metadata": {},
      "source": [
        "## G.  ILAState Enum Values\n",
        "\n",
        "ILA Capture State Transitions:<br>\n",
        ">        IDLE -> PRE_TRIGGER -> TRIGGER -> POST_TRIGGER -> IDLE\n",
        "\n",
        "| Enum Value   | Description\n",
        "|:-------------|:-------------------------------- |\n",
        "| IDLE         | Not armed.                       |\n",
        "| PRE_TRIGGER  | Capturing pre-trigger samples.   |\n",
        "| TRIGGER      | Waiting for trigger.             |\n",
        "| POST_TRIGGER | Capturing post-trigger samples.  |\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "58a8f7df",
      "metadata": {},
      "source": [
        "# Example Steps"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bb759ad4",
      "metadata": {},
      "source": [
        "## 1 - Initialization: Imports and File Paths\n",
        "\n",
        "After this step,\n",
        "- Required functions and classes are imported\n",
        "- URL paths are set correctly\n",
        "- File paths to example files are set correctly"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "ecfb3a41",
      "metadata": {},
      "outputs": [],
      "source": [
        "import os\n",
        "from time import sleep\n",
        "import chipscopy\n",
        "from chipscopy import get_design_files\n",
        "from chipscopy import get_examples_dir_or_die, null_callback\n",
        "from chipscopy import create_session, report_versions, delete_session\n",
        "from chipscopy.api.ila import ILAStatus, ILAState"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "beed989a",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "HW_URL: TCP:localhost:3121\n",
            "CS_URL: TCP:localhost:3042\n",
            "PROGRAMMING_FILE: /scratch/chipscopy/venv/lib/python3.11/site-packages/chipscopy/examples/designs/vck190/production/chipscopy_ced/chipscopy_wrapper.pdi\n",
            "PROBES_FILE:/scratch/chipscopy/venv/lib/python3.11/site-packages/chipscopy/examples/designs/vck190/production/chipscopy_ced/chipscopy_wrapper.ltx\n"
          ]
        }
      ],
      "source": [
        "# Specify locations of the running hw_server and cs_server below.\n",
        "# To make things convenient, we default to values from the following environment variables.\n",
        "# Modify these if needed.\n",
        "\n",
        "CS_URL = os.getenv(\"CS_SERVER_URL\", \"TCP:localhost:3042\")\n",
        "HW_URL = os.getenv(\"HW_SERVER_URL\", \"TCP:localhost:3121\")\n",
        "\n",
        "# specify hw and if programming is desired\n",
        "HW_PLATFORM = os.getenv(\"HW_PLATFORM\", \"vck190\")\n",
        "PROG_DEVICE = os.getenv(\"PROG_DEVICE\", 'True').lower() in ('true', '1', 't')\n",
        "\n",
        "# The get_design_files() function tries to find the PDI and LTX files. In non-standard\n",
        "# configurations, you can put the path for PROGRAMMING_FILE and PROBES_FILE below.\n",
        "design_files = get_design_files(f\"{HW_PLATFORM}/production/chipscopy_ced\")\n",
        "\n",
        "PROGRAMMING_FILE = design_files.programming_file\n",
        "PROBES_FILE = design_files.probes_file\n",
        "\n",
        "print(f\"HW_URL: {HW_URL}\")\n",
        "print(f\"CS_URL: {CS_URL}\")\n",
        "print(f\"PROGRAMMING_FILE: {PROGRAMMING_FILE}\")\n",
        "print(f\"PROBES_FILE:{PROBES_FILE}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3da11861",
      "metadata": {},
      "source": [
        "## 2 - Create a session and connect to the hw_server and cs_server\n",
        "\n",
        "The session is a container that keeps track of devices and debug cores.\n",
        "After this step,\n",
        "- Session is initialized and connected to server(s)\n",
        "- Versions are detected and reported to stdout"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "1dea5a07",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
              "\n",
              "</pre>\n"
            ],
            "text/plain": [
              "\n",
              "\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-style: italic\">                      ChipScoPy Version Information                      </span>\n",
              "┌────────────────────────────┬──────────────────────────────────────────┐\n",
              "│<span style=\"font-weight: bold\">                     Entity </span>│<span style=\"font-weight: bold\"> Version                                  </span>│\n",
              "├────────────────────────────┼──────────────────────────────────────────┤\n",
              "│                  ChipScoPy │ ┌───────────┬──────────────────────┐     │\n",
              "│                            │ │<span style=\"font-weight: bold\"> Attribute </span>│<span style=\"font-weight: bold\"> Value                </span>│     │\n",
              "│                            │ ├───────────┼──────────────────────┤     │\n",
              "│                            │ │     Build │ 2024.1.1717606426    │     │\n",
              "│                            │ │ Timestamp │ Jun 05 2024-09:53:46 │     │\n",
              "│                            │ └───────────┴──────────────────────┘     │\n",
              "│                            │                                          │\n",
              "│ hw_server @ localhost:3121 │ ┌───────────┬──────────────────────────┐ │\n",
              "│                            │ │<span style=\"font-weight: bold\"> Attribute </span>│<span style=\"font-weight: bold\"> Value                    </span>│ │\n",
              "│                            │ ├───────────┼──────────────────────────┤ │\n",
              "│                            │ │    Status │ Connected                │ │\n",
              "│                            │ │     Build │ 1716424495               │ │\n",
              "│                            │ │   Version │ 2024.1                   │ │\n",
              "│                            │ │ Timestamp │ Wed May 22 18:34:55 2024 │ │\n",
              "│                            │ └───────────┴──────────────────────────┘ │\n",
              "│                            │                                          │\n",
              "│ cs_server @ localhost:3042 │ ┌───────────────┬──────────────────────┐ │\n",
              "│                            │ │<span style=\"font-weight: bold\">     Attribute </span>│<span style=\"font-weight: bold\"> Value                </span>│ │\n",
              "│                            │ ├───────────────┼──────────────────────┤ │\n",
              "│                            │ │        Status │ Connected            │ │\n",
              "│                            │ │         Build │ 1714182049           │ │\n",
              "│                            │ │       Version │ 2024.1.0             │ │\n",
              "│                            │ │     Timestamp │ Apr 26 2024-18:40:49 │ │\n",
              "│                            │ │       Package │ 2024.1.1714182049    │ │\n",
              "│                            │ │ Artifact type │ pyinstaller          │ │\n",
              "│                            │ └───────────────┴──────────────────────┘ │\n",
              "└────────────────────────────┴──────────────────────────────────────────┘\n",
              "</pre>\n"
            ],
            "text/plain": [
              "\u001b[3m                      ChipScoPy Version Information                      \u001b[0m\n",
              "┌────────────────────────────┬──────────────────────────────────────────┐\n",
              "│\u001b[1m \u001b[0m\u001b[1m                    Entity\u001b[0m\u001b[1m \u001b[0m│\u001b[1m \u001b[0m\u001b[1mVersion                                 \u001b[0m\u001b[1m \u001b[0m│\n",
              "├────────────────────────────┼──────────────────────────────────────────┤\n",
              "│                  ChipScoPy │ ┌───────────┬──────────────────────┐     │\n",
              "│                            │ │\u001b[1m \u001b[0m\u001b[1mAttribute\u001b[0m\u001b[1m \u001b[0m│\u001b[1m \u001b[0m\u001b[1mValue               \u001b[0m\u001b[1m \u001b[0m│     │\n",
              "│                            │ ├───────────┼──────────────────────┤     │\n",
              "│                            │ │     Build │ 2024.1.1717606426    │     │\n",
              "│                            │ │ Timestamp │ Jun 05 2024-09:53:46 │     │\n",
              "│                            │ └───────────┴──────────────────────┘     │\n",
              "│                            │                                          │\n",
              "│ hw_server @ localhost:3121 │ ┌───────────┬──────────────────────────┐ │\n",
              "│                            │ │\u001b[1m \u001b[0m\u001b[1mAttribute\u001b[0m\u001b[1m \u001b[0m│\u001b[1m \u001b[0m\u001b[1mValue                   \u001b[0m\u001b[1m \u001b[0m│ │\n",
              "│                            │ ├───────────┼──────────────────────────┤ │\n",
              "│                            │ │    Status │ Connected                │ │\n",
              "│                            │ │     Build │ 1716424495               │ │\n",
              "│                            │ │   Version │ 2024.1                   │ │\n",
              "│                            │ │ Timestamp │ Wed May 22 18:34:55 2024 │ │\n",
              "│                            │ └───────────┴──────────────────────────┘ │\n",
              "│                            │                                          │\n",
              "│ cs_server @ localhost:3042 │ ┌───────────────┬──────────────────────┐ │\n",
              "│                            │ │\u001b[1m \u001b[0m\u001b[1m    Attribute\u001b[0m\u001b[1m \u001b[0m│\u001b[1m \u001b[0m\u001b[1mValue               \u001b[0m\u001b[1m \u001b[0m│ │\n",
              "│                            │ ├───────────────┼──────────────────────┤ │\n",
              "│                            │ │        Status │ Connected            │ │\n",
              "│                            │ │         Build │ 1714182049           │ │\n",
              "│                            │ │       Version │ 2024.1.0             │ │\n",
              "│                            │ │     Timestamp │ Apr 26 2024-18:40:49 │ │\n",
              "│                            │ │       Package │ 2024.1.1714182049    │ │\n",
              "│                            │ │ Artifact type │ pyinstaller          │ │\n",
              "│                            │ └───────────────┴──────────────────────┘ │\n",
              "└────────────────────────────┴──────────────────────────────────────────┘\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
              "\n",
              "</pre>\n"
            ],
            "text/plain": [
              "\n",
              "\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "session = create_session(cs_server_url=CS_URL, hw_server_url=HW_URL)\n",
        "report_versions(session)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bf2fa6d1",
      "metadata": {},
      "source": [
        "## 3 - Program the device with the example design\n",
        "\n",
        "After this step,\n",
        "- Device is programmed with the example programming file"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "7b97f1d3",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
              "<span style=\"font-weight: bold\">--&gt; INFO: </span>Programming device with: \n",
              "/scratch/chipscopy/venv/lib/python3.11/site-packages/chipscopy/examples/designs/vck190/production/chipscopy_ced/chi\n",
              "pscopy_wrapper.pdi\n",
              "    \n",
              "</pre>\n"
            ],
            "text/plain": [
              "\n",
              "\u001b[1m--> INFO: \u001b[0mProgramming device with: \n",
              "/scratch/chipscopy/venv/lib/python3.11/site-packages/chipscopy/examples/designs/vck190/production/chipscopy_ced/chi\n",
              "pscopy_wrapper.pdi\n",
              "    \n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "e041633dcd544a52a277596a4a19a2b6",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "Output()"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
            ],
            "text/plain": []
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
              "</pre>\n"
            ],
            "text/plain": [
              "\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# Typical case - one device on the board - get it.\n",
        "device = session.devices.filter_by(family=\"versal\").get()\n",
        "if PROG_DEVICE:\n",
        "    device.program(PROGRAMMING_FILE)\n",
        "else:\n",
        "    print(\"skipping programming\")\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0a0f57e2",
      "metadata": {},
      "source": [
        "## 4 - Discover Debug Cores\n",
        "\n",
        "Debug core discovery initializes the chipscope server debug cores. This brings debug cores in the chipscope server online.\n",
        "\n",
        "After this step,\n",
        "\n",
        "- The cs_server is initialized and ready for use\n",
        "- ILA and VIO core instances in the device are reported"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "8afc6394",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Debug cores setup and ready for use.\n"
          ]
        }
      ],
      "source": [
        "device.discover_and_setup_cores(ltx_file=PROBES_FILE)\n",
        "print(f\"Debug cores setup and ready for use.\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "f692356e",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "0 - D62FB110F1A25D439EB15D9149F450CE   chipscopy_i/counters/ila_fast_counter_0\n",
            "1 - 9125D1429AD25223AECDD656C2856755   chipscopy_i/counters/ila_slow_counter_0\n",
            "2 - C53C0D3572B655B6A8A13A86686D262D   chipscopy_i/noc_tg_bc/noc_bc_axis_ila_0\n"
          ]
        }
      ],
      "source": [
        "# Print out the ILA core instance UUIDs and instance names\n",
        "ila_cores = device.ila_cores\n",
        "for index, ila_core in enumerate(ila_cores):\n",
        "    print(f\"{index} - {ila_core.core_info.uuid}   {ila_core.name}\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "0ca373bf",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "0 - 718A03DBCD265D969EA5C15840AEFD17   chipscopy_i/counters/vio_fast_counter_0\n",
            "1 - 22BC7ED6C4145AAB88C58EAEDFF2B04C   chipscopy_i/counters/vio_slow_counter_0\n",
            "2 - 021098F58FE659EFAD76657E635E53FE   chipscopy_i/noc_tg_bc/axis_vio_0\n",
            "3 - 0E76DEFA789D564080CFA5332A88DB12   chipscopy_i/noc_tg_bc/noc_tg/inst/u_top_axi_mst/u_tg_top/gen_aximm_reg_space.u_reg_space/gen_vio_status_monitor.u_vio_status_monitor\n"
          ]
        }
      ],
      "source": [
        "# Print out the VIO core instance UUIDs and instance names\n",
        "vio_cores = device.vio_cores\n",
        "for index, vio_core in enumerate(vio_cores):\n",
        "    print(f\"{index} - {vio_core.core_info.uuid}   {vio_core.name}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b61fc587",
      "metadata": {},
      "source": [
        "## 5 - VIO Control and ILA Capture\n",
        "\n",
        "ILA and VIO are two important building blocks for debugging applications in hardware.\n",
        "This example design shows how to control IP using a VIO core and capture results with ILA.\n",
        "\n",
        "In this design,\n",
        "- A VIO core controls the counter (reset, up/down, ce, load)\n",
        "- An ILA core captures the counter values\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0087693e",
      "metadata": {},
      "source": [
        "<img src=\"img/capture_data.png\" width=\"400\" align=\"left\">"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "666d52b8",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Using ILA: 9125D1429AD25223AECDD656C2856755  chipscopy_i/counters/ila_slow_counter_0\n",
            "Using VIO: 22BC7ED6C4145AAB88C58EAEDFF2B04C  chipscopy_i/counters/vio_slow_counter_0\n"
          ]
        }
      ],
      "source": [
        "# Grab the two cores we are interested in for the demonstration\n",
        "# As shown above, a counter is connected to the ILA core.\n",
        "# The VIO core controls the counter.\n",
        "\n",
        "ila = device.ila_cores.get(name=\"chipscopy_i/counters/ila_slow_counter_0\")\n",
        "vio = device.vio_cores.get(name=\"chipscopy_i/counters/vio_slow_counter_0\")\n",
        "\n",
        "print(f\"Using ILA: {ila.core_info.uuid}  {ila.name}\")\n",
        "print(f\"Using VIO: {vio.core_info.uuid}  {vio.name}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8661e821",
      "metadata": {},
      "source": [
        "## 6 - Configure the counter using VIO output probes\n",
        "\n",
        "Set up the VIO core to enable counting up, from 0\n",
        "\n",
        "<img src=\"img/vio_control_counter.png\" width=\"300\" align=\"left\">"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "3ab3f1b2",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Counter is now free-running and counting up\n"
          ]
        }
      ],
      "source": [
        "vio.reset_vio()\n",
        "vio.write_probes(\n",
        "    {\n",
        "        \"chipscopy_i/counters/slow_counter_0_SCLR\": 0,\n",
        "        \"chipscopy_i/counters/slow_counter_0_L\": 0x00000000,\n",
        "        \"chipscopy_i/counters/slow_counter_0_LOAD\": 0,\n",
        "        \"chipscopy_i/counters/slow_counter_0_UP\": 1,\n",
        "        \"chipscopy_i/counters/slow_counter_0_CE\": 1,\n",
        "    }\n",
        ")\n",
        "print(\"Counter is now free-running and counting up\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c5703a47",
      "metadata": {},
      "source": [
        "## 7 - Define Status Progress Function\n",
        "- The **status_progress** function will be given to the **ila.monitor_status()** function, as an argument.\n",
        "- The function is called when status changes, but not more often than twice per second.\n",
        "- The argument **future** has a member *progress* of type **ILAStatus**, which contains the status information.\n",
        "- The **status_progress** function,\n",
        "    - prints status to stdout\n",
        "    - cancels the **monitor_status()** function, if 3 waveform windows have been captured.\n",
        "- Note: The monitor function will run in the Event Tread, which handles commands sent to the cs_server.\n",
        "- Important: Do not call an API function which communicates with the cs_server or device, from inside the monitor function. It may put the program in a deadlock."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "0e2b2bb3",
      "metadata": {},
      "outputs": [],
      "source": [
        "def status_progress(future):\n",
        "    \"\"\"Called in Event Thread\"\"\"\n",
        "    st: ILAStatus = future.progress\n",
        "    if st:\n",
        "        print_status(st)\n",
        "        if st.windows_captured >= 3:\n",
        "            print(\"\\nCancelling ILA Status Monitor\")\n",
        "            future.cancel()\n",
        "\n",
        "\n",
        "def print_status(st: ILAStatus):\n",
        "    current_window = min(st.windows_captured + 1, st.windows_requested)\n",
        "    print(\n",
        "        f\"\\nCapture State: {st.capture_state.name} - \"\n",
        "        f\" Windows Captured: {st.windows_captured} of {st.windows_requested}.\",\n",
        "        end=\"\",\n",
        "    )\n",
        "    if st.is_full:\n",
        "        print(f\" - Capture is complete.\")\n",
        "    else:\n",
        "        print(f\" - Samples in current window: \" f\"{st.samples_captured} of {st.samples_requested}.\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f3867835",
      "metadata": {},
      "source": [
        "## 8 - Arm ILA to Trigger on VIO Up/Down virtual switch\n",
        "\n",
        "- Set ILA to trigger when UP/DOWN counter signal edge rises or falls.\n",
        "- Set ILA core to capture on a transition of the UP/DOWN toggle switch\n",
        "- Once transition happens, trigger in the middle of the buffer.\n",
        "- Request 10 windows."
      ]
    },
    {
      "cell_type": "markdown",
      "id": "89cdb12d",
      "metadata": {},
      "source": [
        "<img src=\"img/edge_trigger.png\" width=\"550\" align=\"left\">"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "14d62deb",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "ILA is armed\n"
          ]
        }
      ],
      "source": [
        "ila.reset_probes()\n",
        "ila.set_probe_trigger_value(\"chipscopy_i/counters/slow_counter_0_UP_1\", [\"==\", \"B\"])\n",
        "ila.run_basic_trigger(window_count=10, window_size=8, trigger_position=4)\n",
        "\n",
        "print(\"ILA is armed\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ea1d83c0",
      "metadata": {},
      "source": [
        "## 9 - Start Status Monitor\n",
        "- Define a *done* function *monitor_status_done*, which will be called when status monitoring ends.\n",
        "- Start the Status Monitor.\n",
        "- Passing in the *status_progress* function, defined above.\n",
        "- Get the *future* object from the *monitor_status* function."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "aa784668",
      "metadata": {},
      "outputs": [],
      "source": [
        "def monitor_status_done(future):\n",
        "    print(\"\\nCallback function monitor_status_done() called.\")\n",
        "    if not future.error:\n",
        "        # future.result holds an ILAStatus object.\n",
        "        print_status(future.result)\n",
        "\n",
        "\n",
        "# Called asynchronously, with done callback function.\n",
        "# This thread will continue executing while monitoring of the ILA Status will happen in the event thread.\n",
        "future = ila.monitor_status(\n",
        "    max_wait_minutes=0.5, progress=status_progress, done=monitor_status_done\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2dfa6049",
      "metadata": {},
      "source": [
        "## 10 - Toggle Counter Direction - Monitor Status\n",
        "- Use VIO to toggle counter up/down switch 3 times: DOWN/UP/DOWN.\n",
        "- This will cause the running ILA to trigger 3 times, capturing 3 windows of data.\n",
        "- The *status_progress* function will call *future.cancel()*, after 3 windows.\n",
        "- Observe messages:\n",
        "    - *status_progress* prints capture status.\n",
        "    - *status_progress* prints out message when calling *future.cancel()*.\n",
        "    - *done* function *monitor_status_done* prints message when called."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "dbe4ef90",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "Capture State: TRIGGER -  Windows Captured: 0 of 10. - Samples in current window: 4 of 8.\n",
            "\n",
            "Capture State: TRIGGER -  Windows Captured: 1 of 10. - Samples in current window: 4 of 8.\n",
            "\n",
            "Capture State: TRIGGER -  Windows Captured: 2 of 10. - Samples in current window: 4 of 8.\n",
            "\n",
            "Capture State: TRIGGER -  Windows Captured: 3 of 10. - Samples in current window: 4 of 8.\n",
            "\n",
            "Cancelling ILA Status Monitor\n",
            "\n",
            "Callback function monitor_status_done() called.\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "Changing counter up/down direction.\n",
            "\n",
            "Changing counter up/down direction.\n",
            "\n",
            "Changing counter up/down direction.\n"
          ]
        }
      ],
      "source": [
        "for switch_value in [0, 1, 0]:\n",
        "    print(\"\\nChanging counter up/down direction.\")\n",
        "    vio.write_probes({\"chipscopy_i/counters/slow_counter_0_UP\": switch_value})\n",
        "    # Sleep 2.0 seconds.\n",
        "    sleep(2.0)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c25bec70",
      "metadata": {},
      "source": [
        "## 11 - Status Monitor Completes\n",
        "- *future.result* will block until capture completes or is cancelled.\n",
        "- Status monitoring is cancelled.\n",
        "- *future.result* thows the cancel exception."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "c23e1833",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "****** Status Monitor raised exception: 'Request Cancelled' ******\n",
            "\n",
            "Windows avaliable to upload: 3.\n"
          ]
        }
      ],
      "source": [
        "status = None\n",
        "try:\n",
        "    # future.result is blocking, until monitor_status() function has completed or timed-out or been cancelled.\n",
        "    status = future.result\n",
        "except Exception as ex:\n",
        "    # Catch cancel exception here.\n",
        "    print(f\"\\n****** Status Monitor raised exception: '{ex}' ******\\n\")\n",
        "\n",
        "if status:\n",
        "    print(\"Function monitor_status() has completed.\")\n",
        "else:\n",
        "    ila.refresh_status()\n",
        "\n",
        "print(f\"Windows avaliable to upload: {ila.status.windows_captured}.\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f2797134",
      "metadata": {},
      "source": [
        "## 12 - Upload and Print Data\n",
        "- Print the captured ILA samples and mark the trigger position.\n",
        "- Note that counter changes direction after the trigger mark."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "b0c60199",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Window:0  Window Sample:0   363526694  0x15AAFA26 \n",
            "Window:0  Window Sample:1   363526695  0x15AAFA27 \n",
            "Window:0  Window Sample:2   363526696  0x15AAFA28 \n",
            "Window:0  Window Sample:3   363526697  0x15AAFA29 \n",
            "Window:0  Window Sample:4   363526698  0x15AAFA2A <-- Trigger\n",
            "Window:0  Window Sample:5   363526697  0x15AAFA29 \n",
            "Window:0  Window Sample:6   363526696  0x15AAFA28 \n",
            "Window:0  Window Sample:7   363526695  0x15AAFA27 \n",
            "Window:1  Window Sample:0   161932588  0x09A6E52C \n",
            "Window:1  Window Sample:1   161932587  0x09A6E52B \n",
            "Window:1  Window Sample:2   161932586  0x09A6E52A \n",
            "Window:1  Window Sample:3   161932585  0x09A6E529 \n",
            "Window:1  Window Sample:4   161932584  0x09A6E528 <-- Trigger\n",
            "Window:1  Window Sample:5   161932585  0x09A6E529 \n",
            "Window:1  Window Sample:6   161932586  0x09A6E52A \n",
            "Window:1  Window Sample:7   161932587  0x09A6E52B \n",
            "Window:2  Window Sample:0   364254889  0x15B616A9 \n",
            "Window:2  Window Sample:1   364254890  0x15B616AA \n",
            "Window:2  Window Sample:2   364254891  0x15B616AB \n",
            "Window:2  Window Sample:3   364254892  0x15B616AC \n",
            "Window:2  Window Sample:4   364254893  0x15B616AD <-- Trigger\n",
            "Window:2  Window Sample:5   364254892  0x15B616AC \n",
            "Window:2  Window Sample:6   364254891  0x15B616AB \n",
            "Window:2  Window Sample:7   364254890  0x15B616AA \n"
          ]
        }
      ],
      "source": [
        "ila.upload()\n",
        "samples = ila.waveform.get_data(\n",
        "    [\"chipscopy_i/counters/slow_counter_0_Q_1\"],\n",
        "    include_trigger=True,\n",
        "    include_sample_info=True,\n",
        ")\n",
        "for trigger, sample_index, window_index, window_sample_index, value in zip(*samples.values()):\n",
        "    trigger = \"<-- Trigger\" if trigger else \"\"\n",
        "    print(\n",
        "        f\"Window:{window_index}  Window Sample:{window_sample_index}  {value:10}  0x{value:08X} {trigger}\"\n",
        "    )"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "68f6a2a8",
      "metadata": {},
      "outputs": [],
      "source": [
        "## When done with testing, close the connection\n",
        "delete_session(session)"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "venv",
      "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.11.2"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}
