{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Design rule checking\n", "\n", "A design that renders is not a design that works. Nothing in Quantum Metal\n", "stops you from routing a resonator straight through a feedline, from putting\n", "a launchpad past the chip edge, or from asking for a 90 um fillet on a 60 um\n", "segment. The picture looks plausible; the chip does not.\n", "\n", "`qiskit_metal.validation` is a design rule check (DRC) for that class of\n", "mistake. It reads the built qgeometry tables and reports **findings**:\n", "\n", "```python\n", "from qiskit_metal.validation import validate\n", "\n", "result = validate(design)\n", "print(result.report())\n", "```\n", "\n", "**What the default rules check**\n", "\n", "| Rule | Catches | Default | Source |\n", "|---|---|---|---|\n", "| `metal-overlap` | two components' metal overlapping on one layer -- a short | any overlap > 1 um^2 | -- |\n", "| `metal-spacing` | metal too close to resolve in liftoff/etch | 2 um | GDSII-to-wafer R8 |\n", "| `cpw-gap` | CPW gap so narrow the interface participation ratio spikes | 3 um | GDSII-to-wafer R1 |\n", "| `chip-bounds` | geometry off the die, silently clipped downstream | -- | -- |\n", "| `short-segment` | a segment too short to host its own fillet arc | fillet radius | -- |\n", "| `qubit-clearance` | a CPW running close enough to a qubit pocket to couple | 3x CPW width | project heuristic |\n", "| `ground-continuity` | the ground plane split into disconnected regions | -- | GDSII-to-wafer R9 |\n", "\n", "Severity matters: **ERROR** is geometry that is wrong regardless of intent,\n", "**WARNING** is legal geometry that is probably unintended or spends a physical\n", "budget (loss, stray coupling). Only errors make a result falsy or raise.\n", "\n", "These are a starting point, not a foundry sign-off. Every threshold is a\n", "constructor argument -- see *Tuning the rules* below.\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2026-08-01T02:50:59.530232Z", "iopub.status.busy": "2026-08-01T02:50:59.530010Z", "iopub.status.idle": "2026-08-01T02:50:59.534036Z", "shell.execute_reply": "2026-08-01T02:50:59.532923Z" } }, "outputs": [], "source": [ "# In Colab / Binder, uncomment to install Quantum Metal (lite, no Qt):\n", "# !pip install -q quantum-metal" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2026-08-01T02:50:59.536483Z", "iopub.status.busy": "2026-08-01T02:50:59.536279Z", "iopub.status.idle": "2026-08-01T02:51:01.002700Z", "shell.execute_reply": "2026-08-01T02:51:01.001427Z" } }, "outputs": [], "source": [ "import qiskit_metal as qm\n", "from qiskit_metal import Dict, designs\n", "from qiskit_metal.qlibrary.qubits.transmon_pocket import TransmonPocket\n", "from qiskit_metal.qlibrary.terminations.launchpad_wb import LaunchpadWirebond\n", "from qiskit_metal.qlibrary.terminations.open_to_ground import OpenToGround\n", "from qiskit_metal.qlibrary.tlines.pathfinder import RoutePathfinder\n", "from qiskit_metal.qlibrary.tlines.straight_path import RouteStraight\n", "from qiskit_metal.validation import validate\n", "\n", "\n", "def new_design():\n", " design = designs.DesignPlanar()\n", " design.overwrite_enabled = True\n", " design.chips.main.size.size_x = \"6mm\"\n", " design.chips.main.size.size_y = \"6mm\"\n", " return design\n", "\n", "\n", "def link(design, name, start, end, ori_start, ori_end, cls=RouteStraight, **options):\n", " \"\"\"A CPW between two fresh open terminations -- shorthand for this notebook.\"\"\"\n", " OpenToGround(\n", " design,\n", " f\"{name}_a\",\n", " options=dict(pos_x=start[0], pos_y=start[1], orientation=ori_start),\n", " )\n", " OpenToGround(\n", " design,\n", " f\"{name}_b\",\n", " options=dict(pos_x=end[0], pos_y=end[1], orientation=ori_end),\n", " )\n", " return cls(\n", " design,\n", " name,\n", " options=Dict(\n", " pin_inputs=Dict(\n", " start_pin=Dict(component=f\"{name}_a\", pin=\"open\"),\n", " end_pin=Dict(component=f\"{name}_b\", pin=\"open\"),\n", " ),\n", " **options,\n", " ),\n", " )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## A design with one defect per rule\n", "\n", "Each block below is a mistake that is easy to make and hard to see. Read them\n", "now, then look at the plot and try to spot them before running the check." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2026-08-01T02:51:01.005525Z", "iopub.status.busy": "2026-08-01T02:51:01.005204Z", "iopub.status.idle": "2026-08-01T02:51:02.373935Z", "shell.execute_reply": "2026-08-01T02:51:02.372664Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "02:51AM 01s WARNING [check_lengths]: For path table, component=kink, key=trace has short segments that could cause issues with fillet. Values in (1-1) are index(es) in shapely geometry.\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "02:51AM 01s WARNING [check_lengths]: For path table, component=kink, key=cut has short segments that could cause issues with fillet. Values in (1-1) are index(es) in shapely geometry.\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "02:51AM 02s WARNING [check_lengths]: For path table, component=kink, key=trace has short segments that could cause issues with fillet. Values in (1-1) are index(es) in shapely geometry.\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "02:51AM 02s WARNING [check_lengths]: For path table, component=kink, key=cut has short segments that could cause issues with fillet. Values in (1-1) are index(es) in shapely geometry.\n" ] }, { "data": { "text/plain": [ "['Q1',\n", " 'cross_h_a',\n", " 'cross_h_b',\n", " 'cross_h',\n", " 'cross_v_a',\n", " 'cross_v_b',\n", " 'cross_v',\n", " 'near_a_a',\n", " 'near_a_b',\n", " 'near_a',\n", " 'near_b_a',\n", " 'near_b_b',\n", " 'near_b',\n", " 'thin_a',\n", " 'thin_b',\n", " 'thin',\n", " 'LP',\n", " 'kink_a',\n", " 'kink_b',\n", " 'kink',\n", " 'hug_a',\n", " 'hug_b',\n", " 'hug',\n", " 'split_a',\n", " 'split_b',\n", " 'split']" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "design = new_design()\n", "\n", "TransmonPocket(design, \"Q1\", options=dict(pos_x=\"0mm\", pos_y=\"0mm\"))\n", "\n", "# 1. metal-overlap: two CPWs cross. On one layer, that is a short.\n", "link(design, \"cross_h\", (\"-2.6mm\", \"2mm\"), (\"-1.2mm\", \"2mm\"), \"180\", \"0\")\n", "link(design, \"cross_v\", (\"-1.9mm\", \"1.4mm\"), (\"-1.9mm\", \"2.6mm\"), \"270\", \"90\")\n", "\n", "# 2. metal-spacing: parallel CPWs 1 um apart. Not a short in the CAD, but\n", "# liftoff residue bridges gaps this narrow.\n", "link(design, \"near_a\", (\"0.6mm\", \"2.0055mm\"), (\"2.4mm\", \"2.0055mm\"), \"180\", \"0\")\n", "link(design, \"near_b\", (\"0.6mm\", \"1.9945mm\"), (\"2.4mm\", \"1.9945mm\"), \"180\", \"0\")\n", "\n", "# 3. cpw-gap: a 1 um gap concentrates field in the lossy substrate interface.\n", "link(\n", " design,\n", " \"thin\",\n", " (\"-2.6mm\", \"-2.4mm\"),\n", " (\"-0.6mm\", \"-2.4mm\"),\n", " \"180\",\n", " \"0\",\n", " trace_gap=\"1um\",\n", ")\n", "\n", "# 4. chip-bounds: the launchpad hangs off the die.\n", "LaunchpadWirebond(\n", " design, \"LP\", options=dict(pos_x=\"3.4mm\", pos_y=\"0mm\", orientation=\"180\")\n", ")\n", "\n", "# 5. short-segment: 100 um legs cannot host a 150 um fillet radius.\n", "link(\n", " design,\n", " \"kink\",\n", " (\"1.2mm\", \"-2.6mm\"),\n", " (\"1.3mm\", \"-2.5mm\"),\n", " \"180\",\n", " \"90\",\n", " cls=RoutePathfinder,\n", " fillet=\"150um\",\n", ")\n", "\n", "# 6. qubit-clearance: a CPW skimming Q1's pocket couples to the qubit.\n", "link(design, \"hug\", (\"-1.5mm\", \"0.35mm\"), (\"1.5mm\", \"0.35mm\"), \"180\", \"0\")\n", "\n", "# 7. ground-continuity: a CPW reaching both die edges cuts the ground in two.\n", "link(design, \"split\", (\"-2.994mm\", \"-1.2mm\"), (\"2.994mm\", \"-1.2mm\"), \"180\", \"0\")\n", "\n", "design.rebuild()\n", "design.components.keys()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2026-08-01T02:51:02.377095Z", "iopub.status.busy": "2026-08-01T02:51:02.376809Z", "iopub.status.idle": "2026-08-01T02:51:02.521866Z", "shell.execute_reply": "2026-08-01T02:51:02.520301Z" } }, "outputs": [ { "data": { "image/png": "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B6yOAAAAAJughKeptLTU6ggAAACwCbajAAAAACZjJRwAAMCGmpubrY6AFCjhAAAANrR7926rIyAFtqMAAAAAJqOEp+nkyZM6efKk1TEAAABgA5TwNPX19amvr8/qGAAAALABSjgAAABgMko4AACADfX29qq3t9fqGFgBV0cBAACwoXfeeUeS1NTUZHESJMNKOAAAAGAySjgAAABgMko4AAAAYDJKOAAAAGAyTsxMU3Nzs9URAAAAYBOU8DTt3r3b6ggAAACwCbajAAAAACZjJRwAAMCGSktLrY6AFCjhAAAANnTgwAGrIyAFtqMAAAAAJqOEp6m3t1e9vb1WxwAAAIANsB0lTe+8844kqampyeIkAAAAyHSshAMAAAAmo4QDAADYUDgcVjgctjoGVkAJBwAAsKETJ07oxIkTVsfACijhAAAAgMko4QAAAIDJKOEAAACAySjhAAAAgMm4TniaSktLrY4AAAAAm6CEp+nAgQNWRwAAAIBNsB0FAAAAMNmal/BYLKZvfetb+sM//EOVlpaquLhYjz/+uN566621fmoAAABgXVrzEj47O6tvfOMbeuSRR/Q//+f/1A9/+EMVFRXp8ccf17/927+t9dMDAABsSIcPH9bhw4etjoEVrPme8JycHF25ckVFRUVLtx04cEDNzc367//9v+uJJ55Y6wgAAAAbjsfjsToCUljzlXCXy7WsgN+6raWlRUNDQ2v99PdNOBxWOBy2OgYAAABswJITM6PRqH79619r586dVjz9XTlx4oROnDhhdQwAAADYgCWXKPzWt76lwcFBfeUrX0l5v1AopFAotPRzIBBY62gAAADAmrurEh4MBtMqxI2NjcrKylp2W0dHh1588UV97Wtf0yOPPJLy8cePH9dLL710NxEBAACAdeuuSvjrr7+uZ599dtX7XbhwQTt27Fj6+cyZM/r0pz+tz33uc/ra17626uOff/55HT16dOnnQCCgPXv23E1kAACADaW9vV2SdPDgQYuTIJm7KuFHjx5dVo7TcfnyZT311FP6vd/7PX3/+99P6zF+v19+v/9uIgIAAGxowWDQ6ghIwZQTMwOBgD72sY+pvr5ebW1tXDIHAAAAG9qan5g5Ozurp556SqOjo3r11VfV3d29NOb1etXa2rrWEQAAAIB1Zc1L+M2bN3Xu3DlJ0ic/+cllY5s2bdK1a9fWOgIA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", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig = qm.view(design)\n", "qm.show_inline(fig)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The dashed rectangle is the die outline -- `qm.view` draws it so geometry\n", "placed off the chip is visible rather than silently clipped downstream (pass\n", "`chip_outline=False` for the geometry alone). The launchpad on the right is\n", "plainly outside it.\n", "\n", "The rest are invisible at this zoom. That is the point -- the eye checks\n", "topology, not micron-scale spacing.\n", "\n", "## Run the checks" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2026-08-01T02:51:02.524225Z", "iopub.status.busy": "2026-08-01T02:51:02.523926Z", "iopub.status.idle": "2026-08-01T02:51:02.556150Z", "shell.execute_reply": "2026-08-01T02:51:02.555190Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10 finding(s) from 7 rule(s): 3 error(s), 7 warning(s)\n", " [error] metal-overlap: cross_h and cross_v overlap by 100 um^2 of metal on layer 1 @ (-1.9000, 2.0000)\n", " [error] metal-spacing: near_a and near_b are 1.00 um apart (minimum 2.00 um) @ (2.4000, 2.0000)\n", " [warning] cpw-gap: thin has a 1.00 um CPW gap (minimum 3.00 um) @ (-2.6000, -2.4000)\n", " [error] chip-bounds: LP extends 660.0 um beyond the 'main' chip outline @ (3.5175, 0.0000)\n", " [warning] short-segment: kink.trace segment 0 is 100.0 um long but needs 150.0 um for a 150.0 um fillet @ (1.2500, -2.6000)\n", " [warning] short-segment: kink.trace segment 1 is 100.0 um long but needs 150.0 um for a 150.0 um fillet @ (1.3000, -2.5500)\n", " [warning] short-segment: kink.cut segment 0 is 100.0 um long but needs 150.0 um for a 150.0 um fillet @ (1.2500, -2.6000)\n", " [warning] short-segment: kink.cut segment 1 is 100.0 um long but needs 150.0 um for a 150.0 um fillet @ (1.3000, -2.5500)\n", " [warning] qubit-clearance: hug passes 14.0 um from Q1's pocket (0.64x CPW width; want 3.0x = 66 um) @ (0.0000, 0.3500)\n", " [warning] ground-continuity: ground plane on layer 1 is split into 2 disconnected regions (mm^2: 24.528, 10.705); confirm airbridges or vias tie them together -- this check sees only same-layer metal @ (0.0000, -1.8000)\n" ] } ], "source": [ "result = validate(design)\n", "print(result.report())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Reading the result\n", "\n", "`validate` returns a `ValidationResult`. It is **falsy when there are errors**,\n", "so it drops straight into an `if`. Each `Finding` is a frozen dataclass with\n", "the rule name, severity, message, the components involved, an `(x, y)`\n", "location in millimetres, and the measured `value` against the `limit` it\n", "missed." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2026-08-01T02:51:02.559027Z", "iopub.status.busy": "2026-08-01T02:51:02.558745Z", "iopub.status.idle": "2026-08-01T02:51:02.564847Z", "shell.execute_reply": "2026-08-01T02:51:02.563717Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "passes: False\n", "errors: 3 warnings: 7\n", "\n", "rule: metal-overlap\n", "severity: error\n", "components: ('cross_h', 'cross_v')\n", "location: (-1.9, 2.0)\n", "value/limit: 9.999999999999574e-05 / 1e-06\n" ] } ], "source": [ "print(\"passes:\", bool(result))\n", "print(\"errors:\", len(result.errors), \" warnings:\", len(result.warnings))\n", "\n", "worst = result.errors[0]\n", "print()\n", "print(\"rule: \", worst.rule)\n", "print(\"severity: \", worst.severity)\n", "print(\"components:\", worst.components)\n", "print(\"location: \", worst.location)\n", "print(\"value/limit:\", worst.value, \"/\", worst.limit)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2026-08-01T02:51:02.567027Z", "iopub.status.busy": "2026-08-01T02:51:02.566773Z", "iopub.status.idle": "2026-08-01T02:51:02.571962Z", "shell.execute_reply": "2026-08-01T02:51:02.571231Z" } }, "outputs": [ { "data": { "text/plain": [ "Counter({'short-segment': 4,\n", " 'metal-overlap': 1,\n", " 'metal-spacing': 1,\n", " 'cpw-gap': 1,\n", " 'chip-bounds': 1,\n", " 'qubit-clearance': 1,\n", " 'ground-continuity': 1})" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Group by rule to see the shape of the problem rather than a flat list.\n", "from collections import Counter\n", "\n", "Counter(f.rule for f in result.findings)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Fixing them\n", "\n", "Each finding names the physics it protects, so the fix is not arbitrary.\n", "\n", "1. **`metal-overlap`** -- move `cross_v` clear of `cross_h`. If the crossing is\n", " deliberate, it needs an airbridge: those sit on their own layer and the rule\n", " is layer-aware, so a bridged crossing does not report.\n", "2. **`metal-spacing`** -- open the gap to 200 um. The 2 um default comes from\n", " published superconducting-chip rule sets; your foundry sets the real number.\n", "3. **`cpw-gap`** -- back to the standard 6 um. Narrow gaps push field into the\n", " substrate-metal interface, where two-level-system loss lives.\n", "4. **`chip-bounds`** -- pull the launchpad onto the die, or grow the die.\n", " Off-chip geometry is silently clipped by the GDS and FEM renderers.\n", "5. **`short-segment`** -- either lengthen the legs or shrink the fillet. A\n", " segment must be at least the fillet radius long (twice, if it is an interior\n", " segment with a corner at each end) or the renderer drops the arc and you get\n", " a sharp corner -- a current crowding point.\n", "6. **`qubit-clearance`** -- move the CPW away from the pocket. This is a\n", " *project heuristic*, not a literature value: 3x the CPW width is a\n", " conservative starting point, not a coupling calculation.\n", "7. **`ground-continuity`** -- stop the CPW short of the die edges so ground can\n", " flow around it. A split ground plane is not automatically wrong -- airbridges\n", " tie the pieces together and this rule cannot see them -- but an unintended\n", " split hosts slotline modes." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2026-08-01T02:51:02.574324Z", "iopub.status.busy": "2026-08-01T02:51:02.574040Z", "iopub.status.idle": "2026-08-01T02:51:03.352646Z", "shell.execute_reply": "2026-08-01T02:51:03.351368Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Design rules passed (7 rules ran, no findings).\n" ] } ], "source": [ "design = new_design()\n", "\n", "TransmonPocket(design, \"Q1\", options=dict(pos_x=\"0mm\", pos_y=\"0mm\"))\n", "\n", "link(design, \"cross_h\", (\"-2.6mm\", \"2mm\"), (\"-1.2mm\", \"2mm\"), \"180\", \"0\")\n", "link(design, \"cross_v\", (\"-1.9mm\", \"1.2mm\"), (\"-1.9mm\", \"1.7mm\"), \"270\", \"90\")\n", "link(design, \"near_a\", (\"0.6mm\", \"2.1mm\"), (\"2.4mm\", \"2.1mm\"), \"180\", \"0\")\n", "link(design, \"near_b\", (\"0.6mm\", \"1.9mm\"), (\"2.4mm\", \"1.9mm\"), \"180\", \"0\")\n", "link(\n", " design,\n", " \"thin\",\n", " (\"-2.6mm\", \"-2.4mm\"),\n", " (\"-0.6mm\", \"-2.4mm\"),\n", " \"180\",\n", " \"0\",\n", " trace_gap=\"6um\",\n", ")\n", "LaunchpadWirebond(\n", " design, \"LP\", options=dict(pos_x=\"2.5mm\", pos_y=\"0mm\", orientation=\"180\")\n", ")\n", "link(\n", " design,\n", " \"kink\",\n", " (\"0.9mm\", \"-2.6mm\"),\n", " (\"1.6mm\", \"-2.0mm\"),\n", " \"180\",\n", " \"90\",\n", " cls=RoutePathfinder,\n", " fillet=\"90um\",\n", ")\n", "link(design, \"hug\", (\"-1.5mm\", \"0.7mm\"), (\"1.5mm\", \"0.7mm\"), \"180\", \"0\")\n", "link(design, \"split\", (\"-2.4mm\", \"-1.2mm\"), (\"2.4mm\", \"-1.2mm\"), \"180\", \"0\")\n", "\n", "design.rebuild()\n", "\n", "result = validate(design)\n", "print(result.report())" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2026-08-01T02:51:03.355961Z", "iopub.status.busy": "2026-08-01T02:51:03.355686Z", "iopub.status.idle": "2026-08-01T02:51:03.477278Z", "shell.execute_reply": "2026-08-01T02:51:03.475196Z" } }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig = qm.view(design)\n", "qm.show_inline(fig)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Tuning the rules\n", "\n", "Thresholds are constructor arguments, so a process design kit that differs from\n", "the defaults is a call, not a fork. Pass `rules=` to run a different set --\n", "either a subset, or the defaults with one swapped out." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "execution": { "iopub.execute_input": "2026-08-01T02:51:03.479799Z", "iopub.status.busy": "2026-08-01T02:51:03.479601Z", "iopub.status.idle": "2026-08-01T02:51:03.499259Z", "shell.execute_reply": "2026-08-01T02:51:03.498412Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "8 finding(s) from 1 rule(s): 0 error(s), 8 warning(s)\n", " [warning] cpw-gap: cross_h has a 6.00 um CPW gap (minimum 10.00 um) @ (-1.2000, 2.0000)\n", " [warning] cpw-gap: cross_v has a 6.00 um CPW gap (minimum 10.00 um) @ (-1.9000, 1.2000)\n", " [warning] cpw-gap: near_a has a 6.00 um CPW gap (minimum 10.00 um) @ (2.4000, 2.1000)\n", " [warning] cpw-gap: near_b has a 6.00 um CPW gap (minimum 10.00 um) @ (2.4000, 1.9000)\n", " [warning] cpw-gap: thin has a 6.00 um CPW gap (minimum 10.00 um) @ (-2.6000, -2.4000)\n", " [warning] cpw-gap: kink has a 6.00 um CPW gap (minimum 10.00 um) @ (1.6000, -2.6000)\n", " [warning] cpw-gap: hug has a 6.00 um CPW gap (minimum 10.00 um) @ (-1.5000, 0.7000)\n", " [warning] cpw-gap: split has a 6.00 um CPW gap (minimum 10.00 um) @ (-2.4000, -1.2000)\n" ] } ], "source": [ "from qiskit_metal.validation import DEFAULT_RULES, CPWGapRule, MetalSpacingRule\n", "\n", "# Just one rule, at a tighter limit than the default.\n", "print(validate(design, rules=[CPWGapRule(min_gap=\"10um\")]).report())" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "execution": { "iopub.execute_input": "2026-08-01T02:51:03.501405Z", "iopub.status.busy": "2026-08-01T02:51:03.501214Z", "iopub.status.idle": "2026-08-01T02:51:03.535699Z", "shell.execute_reply": "2026-08-01T02:51:03.534253Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 finding(s) from 7 rule(s): 1 error(s), 0 warning(s)\n", " [error] metal-spacing: near_a and near_b are 190.00 um apart (minimum 250.00 um) @ (2.4000, 2.0000)\n" ] } ], "source": [ "# The 2 um default is a fabrication limit. A crosstalk budget is a separate,\n", "# much looser constraint -- unconnected CPWs kept 250 um apart. Replacing the\n", "# rule rather than adding one matters: both copies would run, and the design\n", "# would be reported twice.\n", "house_rules = [r for r in DEFAULT_RULES if r.name != \"metal-spacing\"]\n", "house_rules.append(MetalSpacingRule(min_spacing=\"250um\"))\n", "\n", "print(validate(design, rules=house_rules).report())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Severity is an argument too. Promote a warning to an error when your process\n", "treats it as a hard rule, and the result turns falsy." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "execution": { "iopub.execute_input": "2026-08-01T02:51:03.538571Z", "iopub.status.busy": "2026-08-01T02:51:03.538352Z", "iopub.status.idle": "2026-08-01T02:51:03.558363Z", "shell.execute_reply": "2026-08-01T02:51:03.556804Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "from qiskit_metal.validation import Severity\n", "\n", "strict_gap = CPWGapRule(min_gap=\"10um\", severity=Severity.ERROR)\n", "print(bool(validate(design, rules=[strict_gap])))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Failing the build\n", "\n", "In a design script or CI job you want the check to stop the run, not print.\n", "`strict=True` raises `DesignRuleViolation` on any error." ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "execution": { "iopub.execute_input": "2026-08-01T02:51:03.560709Z", "iopub.status.busy": "2026-08-01T02:51:03.560503Z", "iopub.status.idle": "2026-08-01T02:51:03.580226Z", "shell.execute_reply": "2026-08-01T02:51:03.579091Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "build stopped:\n", "8 finding(s) from 1 rule(s): 8 error(s), 0 warning(s)\n" ] } ], "source": [ "from qiskit_metal.validation import DesignRuleViolation\n", "\n", "try:\n", " validate(design, rules=[strict_gap], strict=True)\n", "except DesignRuleViolation as exc:\n", " print(\"build stopped:\")\n", " print(str(exc).splitlines()[0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The same thing, without exceptions, at the end of a build script:\n", "\n", "```python\n", "result = validate(design)\n", "if not result:\n", " print(result.report())\n", " raise SystemExit(1)\n", "```\n", "\n", "Quantum Metal gates its own shipped reference designs this way -- see\n", "`tests/test_reference_designs.py`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Writing your own rule\n", "\n", "A rule is any object with a `name`, a `description`, and a `check(design)` that\n", "yields `Finding`s. Subclass `DesignRule` and use the same helpers the built-in\n", "rules use: `chip_bounds`, `component_geometry` (which unions each component's\n", "drawn metal, per layer if you ask), and `representative_point`.\n", "\n", "Here is a fab rule the defaults do not cover: nothing may reach into the dicing\n", "street at the die edge." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "execution": { "iopub.execute_input": "2026-08-01T02:51:03.583336Z", "iopub.status.busy": "2026-08-01T02:51:03.583110Z", "iopub.status.idle": "2026-08-01T02:51:03.593844Z", "shell.execute_reply": "2026-08-01T02:51:03.592739Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2 finding(s) from 1 rule(s): 2 error(s), 0 warning(s)\n", " [error] keep-out-border: kink reaches 400 um into the dicing street @ (1.2521, -2.6026)\n", " [error] keep-out-border: LP reaches 400 um into the dicing street @ (2.6510, 0.0000)\n" ] } ], "source": [ "from shapely.geometry import box\n", "\n", "from qiskit_metal.validation import (\n", " DesignRule,\n", " Finding,\n", " chip_bounds,\n", " component_geometry,\n", " representative_point,\n", ")\n", "\n", "\n", "class KeepOutBorderRule(DesignRule):\n", " \"\"\"Metal must stay clear of the dicing street at the chip edge.\"\"\"\n", "\n", " name = \"keep-out-border\"\n", " description = \"Metal reaches into the dicing street.\"\n", "\n", " def __init__(self, margin=\"400um\", severity=Severity.ERROR):\n", " self.margin = margin\n", " self.severity = severity\n", "\n", " def check(self, design):\n", " margin = design.parse_value(self.margin)\n", " minx, miny, maxx, maxy = chip_bounds(design)\n", " keep_in = box(minx + margin, miny + margin, maxx - margin, maxy - margin)\n", "\n", " for name, geometry in component_geometry(design).items():\n", " outside = geometry.difference(keep_in)\n", " if outside.is_empty:\n", " continue\n", " yield Finding(\n", " rule=self.name,\n", " severity=self.severity,\n", " message=(\n", " f\"{name} reaches {margin * 1000:.0f} um into the dicing street\"\n", " ),\n", " components=(name,),\n", " location=representative_point(outside),\n", " value=outside.area,\n", " limit=0.0,\n", " )\n", "\n", "\n", "print(validate(design, rules=[KeepOutBorderRule()]).report())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## What this does not check\n", "\n", "DRC is a geometry check. It says nothing about whether your resonator is at the\n", "frequency you wanted, whether the coupling is right, or whether the qubit is\n", "anharmonic enough -- those need the analysis notebooks in section 4. It also\n", "knows nothing about your foundry's actual rule deck; the defaults are a\n", "published starting point.\n", "\n", "Three known limits worth stating plainly:\n", "\n", "- **Layers are trusted.** Overlap and spacing are checked per layer, so metal on\n", " layer 30 crossing metal on layer 1 is fine. If your stack does not match that\n", " assumption, the rules will miss real shorts.\n", "- **`net_info` is trusted.** Components joined through a pin are exempt from the\n", " overlap and spacing rules, because a route abutting its termination is not a\n", " short.\n", "- **`ground-continuity` sees one layer.** It reports that the ground is split,\n", " not that a piece is floating -- an airbridge on another layer may well tie the\n", " pieces together.\n", "\n", "## References\n", "\n", "- *From GDSII to Wafer: EDA Design Flow and Data Conversion for Wafer-Scale\n", " Manufacturing of Superconducting Quantum Chips*,\n", " [arXiv:2604.11379](https://arxiv.org/abs/2604.11379) -- the R1 / R8 / R9\n", " thresholds used above.\n", "- *A Review of Design Concerns in Superconducting Quantum Circuits*,\n", " [arXiv:2411.16967](https://arxiv.org/abs/2411.16967) -- crosstalk mechanisms\n", " and airbridge placement.\n", "- Airbridges in Quantum Metal: tutorial 2.15.\n", "- Full worked designs that pass these rules: Appendix A." ] } ], "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.11.15" } }, "nbformat": 4, "nbformat_minor": 4 }