{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "1e8a64e8",
      "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": "3c132aa3",
      "metadata": {},
      "source": [
        "# ChipScoPy DDR 2D Eye Margin Scan Example\n",
        "\n",
        "\n",
        "<img src=\"../img/api_overview.png\" width=\"500\" align=\"left\">"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d29e34b6",
      "metadata": {},
      "source": [
        "## Description\n",
        "This demo shows how to exercise and run Versal DDRMC 2D Margin Scan features\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 and extra libs needed - Please do so, using the command `pip install chipscopy[core-addons,jupyter]`"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "990d1d23",
      "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": "d04009a7",
      "metadata": {},
      "outputs": [],
      "source": [
        "import sys\n",
        "import os\n",
        "import pprint\n",
        "from chipscopy import create_session, delete_session, report_versions\n",
        "from chipscopy import get_design_files\n",
        "from ddr_scan_util import convert_vref_pct_to_code"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "59260290",
      "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": [
        "# Make sure to start the hw_server and cs_server prior to running.\n",
        "# Specify locations of the running hw_server and cs_server below.\n",
        "# The default is localhost - but can be other locations on the network.\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)\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": "code",
      "execution_count": 3,
      "id": "46aeb328",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Which DDRMC target (0..3) for given ACAP\n",
        "# This default value will be readjusted to make sure it points to the first enabled DDRMC\n",
        "DDR_INDEX = 0\n",
        "# Which Rank of the memory interface\n",
        "RANK = 0\n",
        "# Read or Write Margin : \"READ\" \"WRITE\"\n",
        "MARGIN_MODE = \"READ\"\n",
        "# Data pattern used for margin check : \"SIMPLE\" \"COMPLEX\"\n",
        "DATA_PATTERN = \"COMPLEX\"\n",
        "# VREF Percentage Minimum (reccommended: Read :DDR4 25, LP4 5 , Write : DDR4 60  , LP4 10)\n",
        "VREF_PCT_MIN = 25\n",
        "# VREF Percentage Maximum (reccommended: Read:DDR4 50 , LP4 35 , Write : DDR4 90  , LP4 30)\n",
        "VREF_PCT_MAX = 50\n",
        "# Steps to show in the 2D eye scan  ( 1 step takes ~1 second to capture)\n",
        "STEPS = 15\n",
        "# Which nibble (read mode) or byte lane (write) to display\n",
        "DISPLAY_INDEX = 1"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "72dd98da",
      "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": 4,
      "id": "863f015a",
      "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": "f269b80e",
      "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": 5,
      "id": "406b0963",
      "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": "467563acede44b7b9798c014748865a6",
              "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",
        "device.program(PROGRAMMING_FILE)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bf3acdbc",
      "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"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "59b17c61",
      "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": "markdown",
      "id": "6ef9e422",
      "metadata": {},
      "source": [
        "## 5 - Get a list of the integrated DDR Memory Controllers"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "0300cbfb",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "4 integrated DDRMC cores exist on this device.\n",
            " DDRMC instance 0 is enabled\n",
            " DDRMC instance 1 is disabled\n",
            " DDRMC instance 2 is disabled\n",
            " DDRMC instance 3 is disabled\n"
          ]
        }
      ],
      "source": [
        "ddr_list = device.ddrs\n",
        "print(f\"{len(ddr_list)} integrated DDRMC cores exist on this device.\")\n",
        "\n",
        "enabled_found = False\n",
        "for ddr in ddr_list:\n",
        "    if ddr.is_enabled:\n",
        "        print(f\" DDRMC instance {ddr.mc_index} is enabled\")\n",
        "        if not enabled_found:\n",
        "            DDR_INDEX = int(ddr.mc_index)\n",
        "            enabled_found = True\n",
        "    else:\n",
        "        print(f\" DDRMC instance {ddr.mc_index} is disabled\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "747226dd",
      "metadata": {},
      "source": [
        "## 6- Select a target DDR by index and display calibration status"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "bd019919",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Calibration status of DDRMC instance 0 is PASS\n"
          ]
        }
      ],
      "source": [
        "ddr = ddr_list[DDR_INDEX]\n",
        "props = ddr.ddr_node.get_property([\"cal_status\"])\n",
        "cal_status = props['cal_status']\n",
        "print(f\"Calibration status of DDRMC instance {DDR_INDEX} is {cal_status}\")\n",
        "if cal_status != \"PASS\":\n",
        "    print(f\"The DDR controller at index {DDR_INDEX} is not in use\")\n",
        "    # End the HW session early to prevent erroneous exercise of disabled DDRMC\n",
        "    delete_session(session)\n",
        "    exit()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "6a50af2e",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Initialization complete.\n"
          ]
        }
      ],
      "source": [
        "## Initialize and activate the Margin Check feature in the DDRMC\n",
        "ddr.ddr_node.set_property({\"mgchk_enable\": 1})\n",
        "ddr.ddr_node.commit_property_group([])\n",
        "ddr.ddr_node.set_property({\"mgchk_enable\": 0})\n",
        "ddr.ddr_node.commit_property_group([])\n",
        "print(\"Initialization complete.\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "76bcd0b4",
      "metadata": {},
      "source": [
        "## 7 - Setting the 2D eye scan read or write mode"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "a4210d68",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Setting 2D eye for READ margin\n"
          ]
        }
      ],
      "source": [
        "if MARGIN_MODE == \"READ\":\n",
        "    print(\"Setting 2D eye for READ margin\")\n",
        "    ddr.set_eye_scan_read_mode()\n",
        "elif MARGIN_MODE == \"WRITE\":\n",
        "    print(\"Setting 2D eye for WRITE margin\")\n",
        "    ddr.set_eye_scan_write_mode()\n",
        "else:\n",
        "    print(\n",
        "        f\" ERROR: MARGIN_MODE is set to {MARGIN_MODE} which is an illegal value, only READ or WRITE is allowed\"\n",
        "    )"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d49059eb",
      "metadata": {},
      "source": [
        "## 8 - Setting the 2D eye scan data pattern mode"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "9c37e875",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Setting 2D eye for COMPLEX data pattern\n"
          ]
        }
      ],
      "source": [
        "if DATA_PATTERN == \"SIMPLE\":\n",
        "    print(\"Setting 2D eye for SIMPLE data pattern\")\n",
        "    ddr.set_eye_scan_simple_pattern()\n",
        "elif DATA_PATTERN == \"COMPLEX\":\n",
        "    print(\"Setting 2D eye for COMPLEX data pattern\")\n",
        "    ddr.set_eye_scan_complex_pattern()\n",
        "else:\n",
        "    print(\n",
        "        f\" ERROR: DATA_PATTERN is set to {DATA_PATTERN} which is an illegal value, only SIMPLE or COMPLEX is allowed\"\n",
        "    )"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "166f252f",
      "metadata": {},
      "source": [
        "## 9 - Setting the Vref sample min/max range"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "3f278e6c",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Vref Min setting...\n",
            " Requested Read Vref %: 25 actual % : 25.0 \n",
            "Vref Max setting...\n",
            " Requested Read Vref %: 50 actual % : 50.0 \n",
            "Dividing the Vref range into 15 steps\n"
          ]
        }
      ],
      "source": [
        "print(\"Vref Min setting...\")\n",
        "vref_min_code = convert_vref_pct_to_code(ddr, MARGIN_MODE, VREF_PCT_MIN)\n",
        "print(\"Vref Max setting...\")\n",
        "vref_max_code = convert_vref_pct_to_code(ddr, MARGIN_MODE, VREF_PCT_MAX)\n",
        "\n",
        "ddr.set_eye_scan_vref_min(vref_min_code)\n",
        "ddr.set_eye_scan_vref_max(vref_max_code)\n",
        "ddr.set_eye_scan_vref_steps(STEPS)\n",
        "print(f\"Dividing the Vref range into {STEPS} steps\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d2da0e8e",
      "metadata": {},
      "source": [
        "## 10 - Run 2D Margin Scan after settings"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "02638948",
      "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\">Min VRef is set at: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">25.0</span> %, encoded value <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">256</span>\n",
              "</pre>\n"
            ],
            "text/plain": [
              "Min VRef is set at: \u001b[1;36m25.0\u001b[0m %, encoded value \u001b[1;36m256\u001b[0m\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\">Max VRef is set at: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">50.0</span> %, encoded value <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">512</span>\n",
              "</pre>\n"
            ],
            "text/plain": [
              "Max VRef is set at: \u001b[1;36m50.0\u001b[0m %, encoded value \u001b[1;36m512\u001b[0m\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\">Number of VRef steps is set at: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">15</span>\n",
              "</pre>\n"
            ],
            "text/plain": [
              "Number of VRef steps is set at: \u001b[1;36m15\u001b[0m\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "e5863bb67aaf4a25b4f310cfd7beb39e",
              "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\">Info: Margin Scans in progress<span style=\"color: #808000; text-decoration-color: #808000\">...</span>\n",
              "</pre>\n"
            ],
            "text/plain": [
              "Info: Margin Scans in progress\u001b[33m...\u001b[0m\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\"></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": [
        "ddr.run_eye_scan()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "34f0e920",
      "metadata": {},
      "source": [
        "## 11 - Display Scan Plots by a given Unit(nibble/byte) index\n",
        "\n",
        "You can display static or dynamic plots. The display_type controls the display output.\n",
        "- \"static\" is a simple image that can be saved.\n",
        "- \"dynamic\" is an interactive javascript plot.\n",
        "- The default is \"dynamic\"."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "653f908c",
      "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\">Margin window found:  - Rising Edge Clock -  <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">159</span> fine taps at VRef %: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">37.305</span>\n",
              "</pre>\n"
            ],
            "text/plain": [
              "Margin window found:  - Rising Edge Clock -  \u001b[1;36m159\u001b[0m fine taps at VRef %: \u001b[1;36m37.305\u001b[0m\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\">Margin window found:  - Falling Edge Clock -  <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">149</span> fine taps at VRef %: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">35.547</span>\n",
              "</pre>\n"
            ],
            "text/plain": [
              "Margin window found:  - Falling Edge Clock -  \u001b[1;36m149\u001b[0m fine taps at VRef %: \u001b[1;36m35.547\u001b[0m\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "image/png": "[encoded data, 58312 characters]",
            "text/plain": [
              "<IPython.core.display.Image object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "image/png": "[encoded data, 59068 characters]",
            "text/plain": [
              "<IPython.core.display.Image object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "ddr.display_eye_scan(DISPLAY_INDEX, display_type=\"static\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "05aedfb0",
      "metadata": {},
      "source": [
        "Optionally you can return figures as a list for later operations."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "54371d1b",
      "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\">Margin window found:  - Rising Edge Clock -  <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">151</span> fine taps at VRef %: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">37.305</span>\n",
              "</pre>\n"
            ],
            "text/plain": [
              "Margin window found:  - Rising Edge Clock -  \u001b[1;36m151\u001b[0m fine taps at VRef %: \u001b[1;36m37.305\u001b[0m\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\">Margin window found:  - Falling Edge Clock -  <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">149</span> fine taps at VRef %: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">35.547</span>\n",
              "</pre>\n"
            ],
            "text/plain": [
              "Margin window found:  - Falling Edge Clock -  \u001b[1;36m149\u001b[0m fine taps at VRef %: \u001b[1;36m35.547\u001b[0m\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "figs = ddr.display_eye_scan(DISPLAY_INDEX + 1, return_as_list=True)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "939dbc5c",
      "metadata": {},
      "source": [
        "The following loop demonstrates how you can display the graphs from a list created previously.\n",
        "It is easy to display interactive or static images.\n",
        "\n",
        "Here we get the list of figures and output them to png format."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "2145b4d6",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "image/png": "[encoded data, 59144 characters]",
            "text/plain": [
              "<IPython.core.display.Image object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "image/png": "[encoded data, 59424 characters]",
            "text/plain": [
              "<IPython.core.display.Image object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "from IPython.display import Image, display\n",
        "\n",
        "for fig in figs:\n",
        "    # To display interactive images, uncomment the following line:\n",
        "    # fig.show()\n",
        "\n",
        "    # To display a static png image:\n",
        "    image_bytes = fig.to_image(format=\"png\")\n",
        "    ipython_image = Image(image_bytes)\n",
        "    display(ipython_image)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8b647b4e",
      "metadata": {},
      "source": [
        "## 12 - Save the Eye Scan data from latest run"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "id": "0e4a9717",
      "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",
              "Info: Data are being formatted and saved to: myoutput.csv\n",
              "</pre>\n"
            ],
            "text/plain": [
              "\n",
              "Info: Data are being formatted and saved to: myoutput.csv\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "ddr.save_eye_scan_data(\"myoutput.csv\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8570082b",
      "metadata": {},
      "source": [
        "## 13 - Load Eye Scan data from a given data file"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "id": "e474e840",
      "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",
              "Info: Scan data are being loaded successfully from: myoutput.csv\n",
              "</pre>\n"
            ],
            "text/plain": [
              "\n",
              "Info: Scan data are being loaded successfully from: myoutput.csv\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "ddr.load_eye_scan_data(\"myoutput.csv\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4fa6b79c",
      "metadata": {},
      "source": [
        "## 14 - Review overall Scan status and Control group detail from latest run"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 19,
      "id": "9774c9ab",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "{ 'es_data_need_update': 0,\n",
            "  'es_vref_max': 512,\n",
            "  'es_vref_min': 256,\n",
            "  'es_vref_steps': 15,\n",
            "  'eye_scan_error': 'None',\n",
            "  'eye_scan_status': 'DONE',\n",
            "  'mgchk_abort': 0,\n",
            "  'mgchk_ack': 0,\n",
            "  'mgchk_bitslect': 0,\n",
            "  'mgchk_ctrl': 64,\n",
            "  'mgchk_def_rd_vref_0': 373,\n",
            "  'mgchk_def_rd_vref_1': 0,\n",
            "  'mgchk_def_wr_vref': 28,\n",
            "  'mgchk_def_wr_vref_range': 0,\n",
            "  'mgchk_done': 0,\n",
            "  'mgchk_enable': 0,\n",
            "  'mgchk_enable_status': 1,\n",
            "  'mgchk_error': 0,\n",
            "  'mgchk_mode': 1,\n",
            "  'mgchk_pattern_config_0': 0,\n",
            "  'mgchk_pattern_config_1': 0,\n",
            "  'mgchk_pattern_config_2': 0,\n",
            "  'mgchk_pattern_mode': 1,\n",
            "  'mgchk_rank': 0,\n",
            "  'mgchk_rd_vref_0': 508,\n",
            "  'mgchk_rd_vref_1': 0,\n",
            "  'mgchk_rw_mode': 0,\n",
            "  'mgchk_start': 1,\n",
            "  'mgchk_step': 0,\n",
            "  'mgchk_unit': 0,\n",
            "  'mgchk_wr_vref': 0}\n"
          ]
        }
      ],
      "source": [
        "props = ddr.ddr_node.get_property_group([\"eye_scan_stat\", \"eye_scan_ctrl\"])\n",
        "print(pprint.pformat(props, indent=2))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7670bb89",
      "metadata": {},
      "source": [
        "## 15 - (Optional) Report Full DDR config and calibration/margin Info"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "id": "aa608df2",
      "metadata": {},
      "outputs": [],
      "source": [
        "# (uncomment to see report)\n",
        "# ddr.report()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 21,
      "id": "3155d262",
      "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
}
