diff --git a/hardware/eda/Containerfile b/hardware/eda/Containerfile new file mode 100644 index 0000000..fa58eb3 --- /dev/null +++ b/hardware/eda/Containerfile @@ -0,0 +1,28 @@ +# Reproducible EDA toolchain for the PM_K-1 core board. +# +# Why this exists: the system KiCad is 7.0 (no CLI ERC). This pins a known, +# rebuildable environment so the design can be checked/simulated identically +# years from now — fitting for a device meant to outlive its tools. +# +# KiCad 9 -> schematic capture, CLI ERC/DRC, netlist/PDF/Gerber export +# ngspice -> SPICE simulation of the analog audio circuits +# python3 -> scripting / BOM / skidl-style helpers +# +# Build/run via ../eda/run.sh (or: podman build -t pmk1-eda:9.0 .) +FROM docker.io/library/ubuntu:24.04 + +ENV DEBIAN_FRONTEND=noninteractive +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +RUN apt-get update && apt-get install -y --no-install-recommends \ + software-properties-common ca-certificates gnupg && \ + add-apt-repository -y ppa:kicad/kicad-9.0-releases && \ + apt-get update && apt-get install -y --no-install-recommends \ + kicad \ + ngspice \ + python3 python3-pip python3-venv \ + git make && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +WORKDIR /work +CMD ["bash"] diff --git a/hardware/eda/README.md b/hardware/eda/README.md new file mode 100644 index 0000000..626eedb --- /dev/null +++ b/hardware/eda/README.md @@ -0,0 +1,36 @@ +# PM_K-1 EDA environment + +A reproducible container with the tools to design, check, and simulate the core board — +so the work doesn't depend on whatever happens to be installed on a given machine, now or +in 50 years. + +## What's inside +- **KiCad 9** — schematic capture + PCB layout, and a CLI (`kicad-cli`) that can run + **ERC** (Electrical Rules Check) and DRC, and export netlists/PDF/Gerbers. +- **ngspice** — SPICE simulator for validating the analog audio circuits before we commit + copper (op-amp stages, filters, input loading, etc.). +- **python3** — scripting, BOM munging, optional code-defined-schematic helpers. + +## Why a container? +The system KiCad here is 7.0, whose CLI can't run ERC (that arrived in KiCad 8). Rather than +fight the host, we pin a known toolchain. Anyone — including future-you — rebuilds the exact +environment with one command. + +## Use it +```bash +cd hardware/eda +./run.sh # interactive shell, lands in hardware/kicad/ +./run.sh kicad-cli version # confirm KiCad 9 +./run.sh kicad-cli sch erc pm_k1_core.kicad_sch # run ERC on the schematic +./run.sh ngspice -b ../eda/sim/input_loading.cir # run a simulation (cwd is kicad/) +``` +`run.sh` builds the image on first use, then mounts the whole repo at `/work` (so KiCad sees +`hardware/`). Use `RUNTIME=docker ./run.sh …` to use Docker instead of Podman. + +## Layout +``` +eda/ + Containerfile # the pinned toolchain (KiCad 9 + ngspice + python) + run.sh # build-if-needed + run with the repo mounted + sim/ # ngspice decks (SPICE simulations of the analog circuits) +``` diff --git a/hardware/eda/run.sh b/hardware/eda/run.sh new file mode 100755 index 0000000..f93d38c --- /dev/null +++ b/hardware/eda/run.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# Build (first time) and run the PM_K-1 EDA container with the repo mounted. +# +# ./run.sh # interactive shell in hardware/kicad/ +# ./run.sh kicad-cli sch erc pm_k1_core.kicad_sch +# ./run.sh ngspice -b sim/some.cir +# +# Override the runtime with RUNTIME=docker ./run.sh ... +set -euo pipefail + +IMG="pmk1-eda:9.0" +EDA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # hardware/eda +REPO_DIR="$(cd "$EDA_DIR/../.." && pwd)" # repo root +RUNTIME="${RUNTIME:-podman}" + +if ! "$RUNTIME" image inspect "$IMG" >/dev/null 2>&1; then + echo ">> building $IMG (first run, a few minutes)…" >&2 + "$RUNTIME" build -t "$IMG" "$EDA_DIR" +fi + +# Mount the whole repo so KiCad/ngspice see hardware/ ; land in hardware/kicad. +flags=(--rm -v "$REPO_DIR":/work:Z -w /work/hardware/kicad) +[[ -t 0 && $# -eq 0 ]] && flags+=(-it) +exec "$RUNTIME" run "${flags[@]}" "$IMG" "${@:-bash}" diff --git a/hardware/eda/sim/.gitignore b/hardware/eda/sim/.gitignore new file mode 100644 index 0000000..afed073 --- /dev/null +++ b/hardware/eda/sim/.gitignore @@ -0,0 +1 @@ +*.csv diff --git a/hardware/eda/sim/input_loading.cir b/hardware/eda/sim/input_loading.cir new file mode 100644 index 0000000..3d8d554 --- /dev/null +++ b/hardware/eda/sim/input_loading.cir @@ -0,0 +1,47 @@ +* PM_K-1 : input loading -- line receiver (25k) vs Hi-Z instrument buffer (1M) +* +* This is the circuit-level proof of a decision we made by hand: why a guitar/bass +* needs a HIGH-impedance input. A passive pickup is inductive, so the load impedance +* it sees shapes its tone. Plug it into a low impedance and you damp its resonance +* and lose treble + level; a high-Z buffer preserves it. +* +* Pickup model: open-circuit source + winding resistance + inductance + self-capacitance. +* Plus a typical ~300 pF guitar cable. We drive two identical pickup+cable networks +* from one ideal source and load them differently, then compare. +* +* Run: ngspice -b sim/input_loading.cir (from inside the EDA container) + +.title PM_K-1 input loading: line 25k vs instrument 1M + +Vpu src 0 AC 1 + +* --- Branch A: LINE input, ~25k receiver impedance --- +RdcA src a1 6k +LpuA a1 a2 3 +CpuA a2 0 150p +CcabA a2 0 300p +RinA a2 0 25k + +* --- Branch B: INSTRUMENT input, 1M Hi-Z buffer --- +RdcB src b1 6k +LpuB b1 b2 3 +CpuB b2 0 150p +CcabB b2 0 300p +RinB b2 0 1meg + +.ac dec 100 10 100k + +.control +run +meas ac a_1k find vdb(a2) at=1000 +meas ac b_1k find vdb(b2) at=1000 +meas ac a_peak max vdb(a2) from=1000 to=20000 +meas ac b_peak max vdb(b2) from=1000 to=20000 +echo +echo " Level @1kHz : line(25k)= $&a_1k dB inst(1M)= $&b_1k dB" +echo " Resonant peak : line(25k)= $&a_peak dB inst(1M)= $&b_peak dB" +echo " -> the 25k load drags the signal down and flattens the pickup's natural peak;" +echo " the 1M input preserves level and tone. Hence the switchable Hi-Z front end." +wrdata ../eda/sim/input_loading.csv vdb(a2) vdb(b2) +.endc +.end diff --git a/hardware/kicad/.gitignore b/hardware/kicad/.gitignore index e1f523b..aa9de50 100644 --- a/hardware/kicad/.gitignore +++ b/hardware/kicad/.gitignore @@ -1,6 +1,8 @@ # KiCad generated/derived outputs *.pdf *.net +*.svg +*.rpt *-bak *.kicad_prl fp-info-cache