Skip to content
VABISMOPublic

Repository files navigation

QSSC — Quantum Solid State Chip (room temperature)

CI License: Apache-2.0 (non-commercial) Python 3.10–3.12 Tests

A room-temperature solid-state spin-defect quantum platform: a Qiskit backend, an FPGA control stack with PCB design, a validated chip-fabrication protocol, and a web dashboard.

The qubits are spins in NV⁻ centres in CVD diamond, coupled by magnetic dipole and driven by microwaves. The device operates at ~300 K with benchtop electronics: zero-field splitting D ≈ 2.87 GHz, ODMR readout, 64 parallel emitter and detector channels on a 20×20 mm die.

image image

Solid-state spin defects (NV-diamond, hBN V_B⁻, SiC V_Si) keep quantum coherence at ~300 K, so the chip does not require a dilution refrigerator. The canonical default defect is the nitrogen-vacancy (NV⁻) centre in CVD diamond — the only family here whose room-temperature coherence (T₂ ≈ 1.8 ms in ¹²C-enriched diamond) is long enough to compute seriously at 300 K. Zero-field splitting D ≈ 2.87 GHz, room-temperature ODMR readout. hBN V_B⁻ and SiC V_Si are retained as sensor variants.

What's in the box

Layer Where Description
Python core qssc/ QSSCBackend (Qiskit BackendV2), simulator, defect profiles, quantum circuits, fabrication-protocol model
REST backend api/ FastAPI app exposing the simulator, ODMR model, protocol and a circuit runner
Frontend frontend/ React 18 + Vite dashboard (ODMR chart, qubit grid, circuit runner, protocol viewer)
FPGA RTL fpga/rtl 11 Verilog modules (Artix-7) — UART, SPI/ADF4351 PLL, 64-ch CQD emitter drive (3× TLC5947 + dac_ctrl gradient DAC), detector readout (TLV9004 TIA → 4× AD7616 parallel 16-bit ADC, 1 kHz lock-in host-side), hardware QRNG (qrng_entropy von-Neumann extractor), command parser, top-level
Hardware hardware/ KiCad boards (main control + detector head — the two sandwich boards), XDC constraints, CNC G-code, datasheets, HARDWARE_DESIGN.md
Protocol docs/FABRICATION_PROTOCOL_Diamond.md NV-diamond fabrication protocol: CQD emitter array, CVD diamond + NV⁻ defect engineering, on-chip photodetectors, assembly, safety
Tests tests/ software/physics tests (defects, simulator, circuits, backend, API, crypto, cross-platform) — 1148 collected, of which 1109 run in CI — plus a PCB gate track (DRC, connectivity, pin audit, routing, board integrity) that runs locally against an installed KiCad

Quick start

# clone, then work from the repository root (pyproject.toml lives there;
# qssc/ is the package, not a directory you cd into)
python -m venv .venv && . .venv/bin/activate
pip install -e ".[api,dev,hw]"

# run the test suite
python -m pytest --ignore-glob='tests/test_pcb_*'
#   1103 passed, 5 skipped, 1 xfailed  (see ## Testing)

# try the CLI
qssc info                              # backend / defect summary (defaults to NV)
qssc shor 15                           # → factors 3 × 5
qssc odmr                              # ODMR spectrum (NV default, dip at 2.87 GHz)

# start the REST backend (port 8011 matches the Vite dev proxy + api/main.py
# default; the Dockerfile uses PORT env, default 8000, for deploy)
uvicorn api.main:app --port 8011

# in another shell, the dashboard
cd frontend
npm install && npm run dev             # http://localhost:5173

Defect platforms

Platform Defect D (GHz) T₂ @ 300 K Readout err Excitation Role
Diamond NV⁻ (nitrogen-vacancy) 2.87 ~1.8 ms* 8 % 532 nm (green) default / compute
hBN V_B⁻ (boron-vacancy) 3.46 ~2 µs 12 % 561 nm sensor variant
SiC V_Si (silicon vacancy) 0.07 / 0.14 ~40 µs ~15 % 780 nm sensor variant

* The 1.8 ms compute figure is specific to a bulk ¹²C-enriched CVD diamond plate (Balasubramanian 2009: T₂ ≈ 1.8 ms, T₁ ≈ 6 ms at 300 K; single-qubit gate ~25 ns, two-qubit gate ~200 ns, readout ~3 µs) — long enough to compute at room temperature. The as-built lab route instead spin-coats microdiamond powder onto the carrier: those µm-scale grains host NV ensembles with µs–tens-of-µs T₂, so the microdiamond layer is a sensor array, not a compute substrate. The compute claim is scoped to the bulk-CVD material route; both routes share the canonical 20×20 mm two-faced die (see Chip architecture). hBN V_B⁻ and SiC V_Si are likewise sensor variants (their T₂ is too short for serious compute at 300 K, but they sense well).

Chip architecture

The canonical chip is a 20×20 mm two-faced die — 130 bond pads on a 2.5 mm pitch (65 pads per face: 64 electrodes in an 8×8 grid + 1 common), with no through-silicon vias: the emitter face and the detector face are independent surfaces on opposite sides of the bare die. The two-board PCB sandwich (a 150×118 mm main board + a 110×102 mm head board, 6 layers each) is built around that die — the emitter face sits in a plain through-hole 2.54 mm socket on the main board (die removable) and the detector face plugs into the head board's matching through-hole socket; the main board carries the FPGA, the AD7616 readout and the TLC5947 emitter drivers. Everything below is specified relative to that canonical die.

The chip integrates its own emitter and detector arrays and is read electrically: photocurrent → transimpedance amplifier → ADC. The 64 CQD emitters (driven in parallel by 3× TLC5947 constant-current drivers) pump the NV⁻ ensemble (green ~520–540 nm); a resonant microwave X-gate (2.87 GHz) flips the spin to the dark ms=±1 state; the on-chip graphene/MoS₂ detector array measures the resulting photocurrent dip (ODMR). A 650 nm long-pass filter blocks the green pump and passes the NV PL (637–800 nm). Each detector electrode feeds a TLV9004 transimpedance amplifier (16× quad chips), and 4× AD7616 16-bit ADCs digitise all 64 channels (codes 0–65535) over a 9-wire SPI bus, with 1 kHz lock-in demodulation host-side.

flowchart TB
  classDef layer fill:#16203f,stroke:#263056,color:#cfe
  classDef flow fill:#0c1430,stroke:#1d2748,color:#9fb
  classDef mw fill:#2a1530,stroke:#4a2a55,color:#f9a
  classDef elec fill:#102018,stroke:#1f4a2a,color:#9fe

  EM["**64 parallel CQD emitters (3× TLC5947)** — ITO/PEDOT:PSS/CQD-PVA/ZnO/Ag, 520–540 nm"]:::layer
  HOST["**CVD diamond spin-defect host** — NV⁻, D ≈ 2.87 GHz, T₂ ≈ 1.8 ms"]:::layer
  FILT["**650 nm long-pass filter** — blocks green pump, passes NV PL"]:::layer
  DET["**Graphene / MoS₂ photodetector array** — 64 electrodes, bias 0.1–1 V"]:::layer

  EM -- "green pump 520–540 nm (↑)" --> HOST
  HOST -- "NV PL 637–800 nm (↑)" --> FILT
  FILT -- "passes PL, blocks pump" --> DET
  DET -- "photocurrent (↓)" --> TIA["**TLV9004 TIA ×16**"]:::elec
  TIA --> ADC["**4× AD7616 16-bit ADC · 1 kHz lock-in (host)**"]:::elec
  ADC --> CTRL["**Artix-7 control FPGA** (`fpga/rtl`) — emitters, SPI, lock-in"]:::elec

  MW["**ADF4351 MW · 2.87 GHz**"]:::mw
  MW -. "resonant X-gate (phase ≈ π) → ms=±1 dark" .-> HOST
  DET -. "ODMR dip = reduced photocurrent → bit 1" .-> ADC
Loading

Readout: a pumped site with no resonant MW reads bright (high ADC code, bit 0); a resonant X-gate flips the spin to dark (low ADC code, ODMR dip, bit 1). Calibration drives each emitter pixel and reads all detectors to build the emitter-pixel → detector-electrode LUT — no jig.

Qiskit backend

qssc.backend.QSSCBackend is a real BackendV2 subclass with a Target, CouplingMap, QubitProperties and per-site InstructionProperties. Circuits run through Qiskit Aer and return standard get_counts().

Three noise modes (set via the backend noise_mode option):

  • real (default) — the full physics path. For circuits with ≤ 10 active qubits and no opaque compiled blocks it runs a full Aer density-matrix simulation with thermal + depolarizing + readout noise built from the defect's real T₁/T₂ and gate times (O(4ⁿ)). Larger or compiled-block circuits fall back to the analytic decoherence limit computed from the same real T₂ and gate-time parameters plus cumulative per-gate depolarization. A shared signal_retention = exp(−t/T₂)·(1−d₁q)^n₁q·(1−d₂q)^n₂q metric drives both the assessment and the analytic blend, so a 13-qubit Shor run on NV at 300 K retains ~4.7 % of the spin signal and still recovers the factors (3, 5) — NV computes at room temperature; cooling to 1 mK lifts retention only to ~5.5 % because NV is depolarization-limited, not coherence-limited.
  • phenomenological (fast analytic approximation) — ideal Aer statevector + post-hoc per-site readout bit-flip + the same coherence×depolarization damping blended into the distribution. O(n) in qubits; runs in milliseconds.
  • none (ideal) — noiseless statevector only.

aer is accepted as an alias of real. The phenomenological and real modes share the same real T₂/gate-time parameters, so their coherence verdicts agree — only the granularity of the noise differs.

On-chip 2-qubit gate = spin gate (room-temperature entanglement). The QSSC entangles qubits with a ~200 ns microwave / magnetic-dipole spin gate. Spin entanglement at room temperature is documented for NV (Neumann 2008 — electron↔nucleus; Dolde 2013 — two NV electron spins via dipole-dipole, Nature Physics 9:139). Because NV's spin T₂ ≈ 1.8 ms at 300 K ≫ the 200 ns gate, the on-chip 2q gate works at room temperature and NV computes at 300 K (a 13-qubit Shor-15 recovers (3, 5); a Bell pair keeps its |00⟩+|11⟩ correlations). hBN (T₂ ~ 2 µs) and SiC (~ 40 µs) are sensor variants — shallow circuits work at 300 K, deep ones (Shor) do not. The gate fidelity is governed by the spin T₁/T₂ + depolarization budget above (signal_retention).

Per-pixel NV register (within-pixel all-to-all dipole). The 2q gate is a within one microdiamond interaction: each of the 64 die pixels holds a small (~10 NV) register, the NVs a few nm apart, so the 1/r³ dipole couples every pair (complete graph K_n, ODMR-frequency-addressed by one global MW antenna). The qiskit backend (qssc/backend.py) simulates ONE pixel's ~10-NV register as its circuit qubits (64×10 = 640 exceeds the 63-qubit MPS cap, so the 64 pixels are modelled as 64 independent parallel processors at 300 K). Cross-pixel coupling at the 2.5 mm pixel pitch is negligible at 300 K, so the design treats the die as 64 independent registers. The 64-pixel hardware die (the detector array, /api/calibration, the FPGA 64-channel RTL) is unchanged — num_qubits ≈ 10 (the register) and pixels = 64 (the die) now diverge. The dipole physics is grounded in qssc/dipole.py (CZ gate time, addressing leakage, fidelity).

Algorithms included: Shor (QPE period finding), period finding, Grover search, Bell/GHZ, and quantum arithmetic (add / sub / mul / sqrt / log via Draper QFT adder, RGQFT multiplier and phase estimation).

Custom Qiskit circuits

Beyond the demo algorithms, the dashboard and API accept a user-supplied Qiskit circuit — either an OpenQASM 2 string or a Python snippet that builds a QuantumCircuit named qc. The builder (qssc.build_user_circuit) runs the snippet in a restricted namespace (imports limited to qiskit / numpy / math, no file/network/process access) and caps the circuit at 64 qubits.

# API
curl -X POST localhost:8011/api/circuit/custom \
  -H 'Content-Type: application/json' \
  -d '{"code":"from qiskit import QuantumCircuit\nqc=QuantumCircuit(3,3)\nqc.h(0);qc.cx(0,1);qc.cx(1,2);qc.measure(range(3),range(3))","shots":512}'

In the dashboard, select algorithm custom to get a code editor with ready-made Bell / GHZ / QFT / QASM examples.

Security note: this is intended for a local lab / demo tool, not a public multi-tenant service. The sandbox is a restricted namespace, not a hardened isolation boundary.

FPGA control stack

A single Artix-7 XC7A35T-1CSG324C orchestrates 64 individual on-chip CQD ASE/LED emitters (green ~520–540 nm, constant-current-driven by 3× TLC5947 PWM drivers off a +12 V emitter rail), the on-chip graphene/MoS₂ photodetector array read through 16× TLV9004 TIAs into 4× AD7616 parallel 16-bit ADCs with 1 kHz lock-in demodulation host-side, an ADF4351 microwave PLL, and a host UART link. The chip integrates its own emitter and detector arrays and is read electrically: the ODMR dip is a reduction of photocurrent at resonance. The RTL (fpga/rtl/, 11 modules + a self-checking testbench) is parse-verified with pyverilog, functionally simulated with iverilog, and synthesised with yosys synth_xilinx (xc7, -abc9 pinned) — the testbench drives DRIVE_EMITTER 3 100 (fires one emitter + OK reply), READ_RNG 4 (asserts the 8-hex-digit debiased word + the " 00064 0 0" raw-sample stats footer) and READ_DETECTORS (asserts the 64-sample stream 1234 1234 … 1234\n, 320 bytes, 19/19 checks pass). The yosys synthesis maps the design to the Series-7 cell library and confirms it fits the XC7A35T-1CSG324C (8377 LUT / 40.3 %, 7442 FF / 17.9 %, 1313 CARRY4 / 25.2 %, 9 DSP48E1 / 10.0 %, 0 inferred latches, 0 blackboxes, 18528 tech-mapped cells — the committed numbers live in fpga/synth/SYNTH_REPORT.md). Synthesis runs the staged tree — fpga/rtl passed through the same patch chain the Vivado build applies (fpga/synth/stage_rtl.py) — so the gate measures the configuration that ships. Those three checks run in CI whenever fpga/** changes (the FPGA job is path-filtered: a full yosys run costs ~45 min) and locally with bash fpga/synth/run_synth.sh. (A first iverilog run caught two real handshake bugs pyverilog could not — a readout busy race and a missing consumer-ack — now fixed.) Pin assignments live in fpga/constraints.xdc; the synthesis flow + report live in fpga/synth/ (see hardware/HARDWARE_DESIGN.md §17).

Boards

The same RTL drives both board variants — the readout goes to an external AD7616 over SPI, so nothing depends on the Xilinx XADC hard block, and only the .xdc pin map changes. Toolchain for both is the free Xilinx Vivado; the host link is a USB cable to the board's USB-UART bridge at 115200-8-N-1.

Variant FPGA Where Status
Custom QSSC PCB Artix-7 XC7A35T-1CSG324C hardware/pcb/, pins in fpga/constraints.xdc design artefact: boards, XDC and yosys synthesis complete; bitstream packaging outstanding
Home-lab QMTECH Artix-7 XC7A15T (stock dev board) fpga/qmtech/ verified on hardware: bitstream built and flashed, JTAG reports init 1 done 1
  • QMTECH (home lab): bash fpga/qmtech/build.sh, then bash fpga/qmtech/flash_qmtech.sh. Wiring: fpga/INTERCONNECT.md; pin map: fpga/qmtech/PINMAP.md.
  • Custom QSSC PCB: JTAG through a Digilent JTAG-HS3 or Xilinx Platform Cable USB II into the 6-pin header (TCK=E10 TMS=E12 TDI=E11 TDO=E13), UART through the on-board FT232RL. The Digilent Arty A7-35T and Cmod A7-35T also run this firmware with a remapped pin file (HARDWARE_DESIGN.md §1A).

The host protocol is a small ASCII UART command set (115200 baud, 8-N-1, \n-terminated; all numbers decimal integers — see hardware/HARDWARE_DESIGN.md §5 for the full specification):

Command Action Reply
DRIVE_EMITTER <index> <duration_ms> fire emitter <index> (0–63) OK
APPLY_PULSE <qubit> <freq_khz> <amp> <duration_ns> <phase> program ADF4351 + gate the MW pulse OK
READ_DETECTOR <site> digitise one detector electrode (AD7616) <code>
READ_DETECTORS sweep all 64 electrodes, stream codes <code> <code> … (64)
CALIBRATE drive each emitter + read detectors, build emitter→detector LUT OK

freq_khz is the RF carrier in kHz (e.g. 2870000 for 2.87 GHz NV⁻, 3460000 for 3.46 GHz hBN V_B⁻); the pulse is split across the ADF4351 and the RF switch: freq_khz → PLL carrier, phase (milliradians) → R1 PHASE register, amp 0–3 → R4 RF_PWR output-power index, duration_ns → the mw_gate RF-switch pin (a gate timer counts duration_ns/10 cycles at 100 MHz). The FPGA does not shape the analog envelope — an external AWG/modulator does. Detector codes are 16-bit ADC values (0–65535, AD7616). The Python EmitterController / DetectorInterface / MicrowaveController emit exactly this integer form, so the same control code drives the SimulatedFPGA and a real board.

Connecting the board + flashing the firmware

Hardware. Target FPGA: Artix-7 XC7A35T-1CSG324C on the custom QSSC PCB (the same RTL also runs on a Digilent Arty A7-35T / Cmod A7-35T — only the .xdc pin map changes; see HARDWARE_DESIGN.md §1A). Two cables:

  1. JTAG — to flash the bitstream. Use a Digilent JTAG-HS3 or Xilinx Platform Cable USB II into the board's 6-pin JTAG header (TCK=E10 TMS=E12 TDI=E11 TDO=E13, see fpga/constraints.xdc). On an Arty A7, the on-board USB-JTAG does this — no separate cable.
  2. UART — the host command link. A USB-A → USB-B (or micro-USB) cable to the board's USB-UART bridge (FT232RL / FT2232H), which enumerates as a serial port: /dev/ttyUSB0 on Linux, /dev/cu.usbserial-* on macOS, COM3 on Windows. Link is 115200 baud, 8-N-1, \n-terminated ASCII.

Host install (with the serial extra). The base install has no pyserial; the real-board path needs the optional [hw] extra:

pip install -e ".[hw]"      # pulls pyserial>=3.5
export QSSC_FPGA_PORT=/dev/ttyUSB0   # the UART port above

Build the bitstream (on a machine with Xilinx Vivado — Vivado is not in CI). Synthesis is yosys; place-and-route + bitstream write need Vivado:

# 1. yosys synthesis -> fpga/synth/qssc_top.edif (runs headless, no Vivado)
cd fpga/synth && ./run_synth.sh

# 2. Vivado place-and-route + bitstream (batch Tcl)
vivado -mode batch -source - <<'TCL'
set part xc7a35tcsg324-1
read_edif qssc_top.edif
read_xdc ../constraints.xdc
link_design -part $part -top qssc_top
opt_design; place_design; route_design
report_timing_summary
write_bitstream -force qssc_top.bit
TCL

The repo ships the already-synthesised fpga/synth/qssc_top.edif, so you can skip step 1 and go straight to Vivado with the EDIF + fpga/constraints.xdc.

Flash. Open Vivado Hardware Manager: Open target → Auto-connect (the JTAG-HS3 / Platform Cable appears), Program device → select qssc_top.bit. To boot from power-on without the cable, also write it to the on-board W25Q128 QSPI flash (Vivado Add configuration flash device → write_bitstream with the SPI config). Alternatively, openFPGALoader -b artix_a7_35t qssc_top.bit works for the Arty A7.

Verify the link. With the board flashed and QSSC_FPGA_PORT set, start the stack and probe:

uvicorn api.main:app --port 8011 &        # API
cd frontend && npm run dev &              # dashboard on :5173
.venv/bin/rq worker qssc --url redis://localhost:6379/0 &   # async job queue
curl localhost:8011/api/fpga/probe        # -> {"connected": true, "id": "QSSC v1", ...}

In the dashboard, switch the top-level toggle to Hardware: the indicator turns green (FPGA connected — QSSC v1 on /dev/ttyUSB0). Run a circuit → the result is labelled source: hardware · I/O: real. With no board (or QSSC_FPGA_PORT unset), the same switch shows a red No FPGA detected banner and never silently falls back to the simulator.

Firmware status. All 19 verbs are implemented in the RTL: DRIVE_EMITTER, SET_EMITTER, DRIVE_PATTERN, CLEAR_EMITTERS, READ_DETECTOR, READ_DETECTORS, CLEAR_DETECTORS, APPLY_PULSE, CALIBRATE, READ_RNG, ID, STATUS, RESET, ODMR_SWEEP, RUN_SEQUENCE, READ_LOCKIN, READ_LOCKINP, RUN_ALL_ODMR, SET_GRADIENT. /api/fpga/probe asks the board for ID (it answers QSSC v1) and reports connected: false when nothing answers. READ_GYRO still runs on the simulator in Hardware mode under an explicit simulated label — the switch never falls back silently.

Fabrication protocol

docs/FABRICATION_PROTOCOL_Diamond.md is the NV-diamond build: CQD emitter array, CVD diamond + NV⁻ defect engineering, on-chip graphene/MoS₂ photodetectors, device assembly and safety — each step with target parameters and expected outcomes. It is grounded in landmark publications (Gottscholl Nature Physics 2020; Hernandez Nature Nanotechnol. 2008; Coleman Science 2011; Kianinia ACS Photonics 2020) and is explicit about what is established versus aspirational (the CQD source is amplified spontaneous emission, not a laser).

The API and dashboard serve the same protocol from structured Python data in qssc/protocol.py (/api/protocol).

Features & inventions

The chip + stack carry a set of hardware and software features we catalog as "inventions" (full status in docs/INVENTIONS.md). Each is marked SIM ✅ (implemented + tested in the simulator), HW-fits (runs on the current PCB with a firmware verb), needs-HW (needs a PCB addition), or needs-cryo (only works cold).

Implemented in the simulator + API (SIM ✅):

# Feature What it does
1 64-pixel vector magnetometer 4-axis NV⟨111⟩ doublet splits → B-vector per pixel, gradiometric sign-locking
2+ Prime-coprime readout + denoiser 16 prime-period lock-in channels, exactly orthogonal, zero cross-talk
3 Nuclear-spin memory (NV+¹³C) ¹³C memory qubit doubles the register via SWAP (needs RF channel for HW)
4 64-parallel distributed computing 64 independent ~10-NV pixels = 64× throughput (not one big circuit)
5 Gradient register width Field gradient makes per-pixel width a MEASURED quantity; coil+DAC now on the PCB (PR #79)
6 Sub-pixel detector centroiding Charge-sharing on the graphene sheet → 64·S spatial channels (no qubit gain)
7 N-shot lock-in integration 1/√N averaging raises measured width (no HW)
9 Classical anti-noise filter stack 300 K filter stack (servo/iso/shield/feed-forward/CM/DD) protects SNR + extends T₂
13 Compressed-sensing super-res ODMR OMP sparse recovery over the gradient-bin dictionary; deconvolves overlapping lines, lowers the SNR bar → more measured qubits
14 Bayesian quantum-limited readout One-sided Bonferroni-corrected matched-filter detector extracts marginal lone-NV lines the hard bar misses (~2× width)
19 Tensor-gradient magnetic imaging 4-axis readout + on-board gradient coil → per-pixel B-gradient tensor + dipole source localizer (position + moment)

Application features (SIM ✅, merged): quantum RNG (Ed25519 keypair + cert), BB84 QKD (intercept-resend Eve), 4-stage ODMR calibration (per-pin Ramsey T₂*/Hahn T₂ map), on-chip sensors (compass / gyro / magneto-optic image / ferro / nav / thermal / current).

Documented candidates (not yet built): ¹³C nuclear cluster register (Inv 10), NV nitrogen nuclear-spin register (Inv 11), resonant spin-to-charge readout (Inv 12), parallel VQE/QAOA (Inv 15), quantum kernel estimation / QSVM (Inv 16), distributed Heisenberg-limited sensing (Inv 17), small QEC code (Inv 18).

Cryo-only (not at 300 K): magnon inter-pixel entanglement bus (Inv 8) — the magnon thermal occupation n_th ≈ 2 200 at 300 K is inseparable from the signal; only cooling (~150 mK) changes it. This is the only route to cross-pixel entanglement (one big register instead of 64 independent pixels).

Qubit-count picture: 64 pixels × one compute microdiamond (≤300 NVs) each. The per-pixel width is min(resolvable lines, NVs present), measured by counting ODMR lines that clear SNR=4. With the on-board gradient (Inv 5) + the anti-noise stack (Inv 7+9) the measured width peaks at ~70 qubits/pixel (gradient 2–3 MHz/µm); the theoretical cap is 300 qubits/microdiamond (one per NV, needs gradient ≥ 7.5 MHz/µm), today noise-bound. Inventions 13 (sparse super-res) + 14 (Bayesian readout) close that 70 → 300 gap by recovering dim lone-NV lines from the noise — the Bayesian detector alone roughly doubles the measured width on the same spectrum. Cross-pixel entanglement (Inv 8, cryo) is the only way to pool pixels into one register.


Scope note

This is an engineering design + simulator, not a claim of a working fault-tolerant processor. The software stack runs and is tested; the fabrication protocol is validated against the literature; the FPGA RTL and PCB are design artefacts. No result is claimed that the underlying science does not support.

Testing

# what CI runs on every push/PR — 1109 tests, no KiCad required
python -m pytest --ignore-glob='tests/test_pcb_*'
#   1103 passed, 5 skipped, 1 xfailed     ← the "Tests" badge above

# everything, including the PCB gate track — needs a system KiCad
# (kicad-cli + the pcbnew python binding)
python -m pytest                          # 1148 collected

# the two things that are *not* pytest, run separately
bash fpga/synth/run_synth.sh              # yosys synthesis gate (~45 min)
cd fpga && iverilog -g2012 -DFAST_SIM -o /tmp/tb.vvp -s tb_top_level \
        rtl/*.v sim/tb_top_level.v && vvp /tmp/tb.vvp   # → ALL CHECKS PASSED
Track Where it runs Needs
Python suite — 1109 collected CI, every push and PR nothing beyond pip install -e ".[api,dev,hw]"
FPGA parse (pyverilog) + simulate (iverilog) + synthesise (yosys) CI, only when fpga/** changes (path-filtered — one run costs ~45 min) iverilog, pyverilog, oss-cad-suite (CI installs all three)
PCB DRC / connectivity / pin audit / routing — 39 tests in 13 files local only system KiCad with kicad-cli pcb drc
Analog loop-filter bandwidth CI, every push ngspice

CI is the merge gate and the deploy gate: .github/workflows/ci.yml must be green, and deploy.yml re-checks that before publishing anything.

Deployment (free hosting + CI/CD)

The whole stack — static dashboard plus the full Python simulator API — runs on free hosting, and the deploy is gated on tests: a red CI run never reaches the deploy workflow.

Layer Host Plan What runs there
Dashboard (React/Vite) GitHub Pages free static frontend/dist at <owner>.github.io/QSSC/
API (FastAPI + qiskit Aer) Render free web service Dockerfile → uvicorn api.main:app; no Redis/Mongo needed (api/jobs.py falls back to an in-process executor)

Memory check: import ~90 MB, a cold Shor-15 run ~100 MB, the heaviest density-matrix path (≤10 qubits) adds ~16 MB — comfortably inside Render's 512 MB free tier, so the simulator is 100% functional, not a stub. The Dockerfile is host-agnostic, so Fly.io, Hugging Face Spaces or Koyeb are drop-in alternatives if Render's free tier changes; render.yaml is provided for one-click Render Blueprint deploys.

Test-gated auto-deploy. .github/workflows/deploy.yml fires only as a workflow_run after the CI workflow has completed successfully on main (a failed test/parse/sim run blocks both deploys). It then:

  1. Frontend → GitHub Pages — builds the dashboard with VITE_API_BASE baked in, uploads frontend/dist, deploys to Pages.
  2. API → Render — POSTs to the Render deploy hook, which re-deploys the Docker service from the latest green main (skips gracefully if the hook secret is unset, so the frontend still ships on its own).

One-time repo configuration (Settings):

  • Pages → Source = "GitHub Actions" (so the workflow, not the gh-pages branch, publishes the dashboard).
  • Repository variable VITE_API_BASE = the public API URL, e.g. https://qssc-api.onrender.com. The dashboard calls this for every /api/* request (see frontend/src/api.js). Without it, the dashboard defaults to a same-origin base and API calls 404 on Pages.
  • Repository secret RENDER_DEPLOY_HOOK_URL = Render's deploy-hook URL (Render dashboard → the qssc-api service → Settings → Deploy Hook). Create the service first (from render.yaml), then paste its hook here.
  • Public URLs after first deploy: dashboard https://<owner>.github.io/QSSC/, API https://qssc-api.onrender.com.

Security caveat (read before pointing the API at the public internet). The API exposes POST /api/circuit/custom, the custom-circuit sandbox. As the /api/circuit/custom docstring states, this is a restricted namespace, not a hardened isolation boundary — it is intended as a local lab / demo tool, not a public multi-tenant service. Deploying the full API (as requested, "100% functional") puts that endpoint on the public internet. For a hardened public deployment, disable /api/circuit/custom at the reverse proxy or gate it behind authentication; the rest of the API is read/simulate-only and is safe to expose.

Documentation index

Hardware

  • hardware/HARDWARE_DESIGN.md — the full hardware design document: system overview + block diagram, BOM, power sequencing, clocking, the FPGA↔PC UART protocol (§5), ADF4351 loop filter & RF path, on-chip CQD emitter driver math (3× TLC5947), on-chip photodetector readout (TLV9004 TIA + 4× AD7616 parallel 16-bit ADC → 9-wire SPI, host-side 1 kHz lock-in, 650 nm long-pass filter), microwave antenna/CPW, controlled- impedance routing, decoupling, the two 6-layer PCB stackups, critical-net trace geometry, CNC G-code files, the KiCad project, and a references list (ADF4351 / XC7A35T / GVA-84+ / AD7616 / TLC5947 / TLV9004 / NV readout).
  • fpga/rtl/ — 11 Verilog modules: top_level, command_parser, uart_rx/uart_tx, spi_master (ADF4351), adf4351_ctrl, tlc5947_ctrl (emitter PWM), emitter_array (64 parallel CQD emitters via 3× TLC5947), dac_ctrl (MCP4921 gradient-coil DAC), adc_reader (4× AD7616 parallel 16-bit ADC, 1 kHz lock-in host-side), qrng_entropy (dark-channel LSB von-Neumann extractor, READ_RNG + entropy-health-gated key material, HARDWARE_DESIGN.md §15E).
  • fpga/constraints.xdc — Artix-7 CSG324 pin assignments and timing constraints (100 MHz TCXO, TLC5947 emitter SPI, AD7616 detector SPI, ADF4351 SPI).
  • fpga/sim/tb_top_level.v — self-checking testbench.
  • hardware/gcode/ — CNC G-code toolpaths for the chip carriers and sensor fixtures (described in HARDWARE_DESIGN.md §14).
  • hardware/pcb/ — KiCad PCB project for BOTH sandwich boards (qssc.kicad_* main + chip_module.kicad_* detector head, generated by tools/gen_qssc_kicad.py and routed headless by tools/route_signals.py + tools/route_qssc_pcb.py) — ERC-clean schematics (0 errors) + DRC-gated 6-layer boards (main 210×140 mm HDI + detector head 150×140 mm, full netlist on pads; head DRC is at 0 violations and held there by an empty-allowlist ratchet in tests/test_pcb_head.py). The test suite gates DRC, zone-fill freshness, connectivity graph, per-datasheet pin audit, routing rules, board-uuid uniqueness, track-width rules, and the J12 board-to-board pinout mirror — see tests/test_pcb_*.py. These PCB gates are local-only: they need a system KiCad (kicad-cli pcb drc + the pcbnew binding) and no hosted runner provides a usable version, so CI runs them nowhere — run pytest tests/test_pcb_*.py on a machine with KiCad. KNOWN: the head's die-bus escape is re-routed and 100 of the 129 regressed die-bus nets are closed, with 15 DET_IN + 14 DET_TIA still open (ratcheted in tests/test_pcb_connectivity.py). On the main board only the USB-C D- pair tie (USB_DM) remains split.

Fabrication protocol

Architecture & decision records

  • docs/architecture/ — Mermaid diagram hub complementing the diagrams above: end-to-end system overview (incl. host software), the READ_DETECTORS signal chain, the FPGA RTL module graph, and the power/clock trees.
  • docs/adr/ — architecture decision records (ADR-0001 … ADR-0008): why the readout pivoted to 4× AD7616, why the die sits in a two-board sandwich, why 3× TLC5947 on +12 V_EMIT, why CSG324, and the docs-layout decisions (incl. datasheets staying in hardware/).
  • hardware/datasheets/DATASHEETS.md — per-component datasheet index; the authoritative component reference (kept next to the hardware design doc, see ADR-0008).

Contributors

VABISMO RTL, backend, FPGA board ports, PCB design, CI/CD, docs
bartman081523 hardware & electrical audit, PCB repairs, gradient board, issue triage (#162–#172)

Minimal contribution rules

  1. Branch from main, one concern per PR, and fill in the PR template (What / Why / Test).
  2. Code, comments and commit messages in English; commit style is <area>(<scope>)?: <imperative summary>.
  3. CI green before review. Locally: pip install -e ".[api,dev,hw]", then pytest --ignore-glob='tests/test_pcb_*' (1103 passed, 5 skipped, 1 xfailed) and ruff check --select=E9,F63,F7,F82,F401,F841 .
  4. Hardware/PCB changes additionally run pytest tests/test_pcb_*.py with KiCad installed, and python3 tools/gen_bom.py when the BOM changes.
  5. FPGA changes additionally run the iverilog testbench and bash fpga/synth/run_synth.sh.
  6. A change to behaviour, numbers, pinouts or counts updates the matching doc in the same PR.

Evidence norms, the commit-style examples and the agent guidance live in CONTRIBUTING.md and AGENTS.md; defects go through the issue templates.

License

Apache License 2.0 with a non-commercial use restriction — see LICENSE. Academic research, teaching and personal use are fine; commercial use requires written permission from the author.

Releases

Packages

Contributors

Languages