Skip to the content
6 layers290.7 × 322 mmBoard presignal, the printed circuit board in 3D

Board presignal

epatel/discrete650214

A MOS 6502 CPU rebuilt from 4,051 discrete transistors on a 291x322mm six-layer board that reproduces the original die layout

Size
290.7 × 322 mm
Copper layers
6
Thickness
1.6 mm
Parts
5,425
Nets
2,624
Pads
14,952
Tracks, vias
7,252, 3,852
Pours
2
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
25 Jul 2026
Updated
18 Oct 2026

Overview

Board presignal is an open-source printed circuit board by epatel, from the epatel/discrete6502 repository on GitHub. It is a 6-layer board of 290.7 × 322 mm with 5,425 parts on 2,624 nets, routed with 7,252 tracks and 3,852 vias.

It is built around the AB4, BSS138K and 1N4148WS, with the AB1, AB10 and AB14 among its other parts. Its parts include 4,051 transistors, 1,110 resistors, 156 capacitors, 67 diodes and 1 IC. It belongs with the retro computing and games boards and the RP2040 and RP2350 boards of this library.

Main components

12

README

README.md

Made with Claude

discrete6502

A complete, verified design for a MOS 6502 CPU built from 4,051 discrete surface-mount transistors (3,996 logic + 55 LED drivers), laid out as a 291 × 322 mm six-layer PCB that visually reproduces the original 6502 die — every FET sits at its transistor's die-true position, 55 LEDs blink the register bits in place, and a ring of die-scaled bond pads around the edge takes crocodile clips.

The design is finished and every check passes, but no board has been built yet — nothing here has been proven in copper, only in simulation and geometry. See Status for what that means.

→ Illustrated project introduction — start here if you want the story rather than the build.

Inspired by the MOnSter 6502 (concept only — independently designed and simplified). Logic ground truth is the visual6502 reverse-engineered netlist, captured from photographs of a real decapped 6502.

Front (the die)Back (passives + Pico site)
Front of the board: 4,051 transistors at their die-true positions, ringed by gold bond padsBack of the board: pull-up resistors, decoupling capacitors and the unpopulated Pico site

Status

Rev A ordered 2026-07-28 and in production — 5 boards, 4 of them assembled. Both manufacturer confirmation gates passed (PCB stackup verified by measurement, SMT placement verified on the DFM image). Release record with file fingerprints and full verification results: gen/fab/RELEASE.md; step-by-step ordering checklist: gen/fab/ordering.html. Bring-up (M6) starts when boards arrive.

Verified against the exact board in that package: switch-level equivalence PASS, board-vs-netlist parity 0 errors, independent copper connectivity 0 broken, DRC 0 electrical violations (2 benign items inside the Pico library footprint) and 0 unconnected.

MilestoneState
M1 Research (visual6502 data, MOnSter lessons)✅
M2 Feasibility (dynamic NMOS, pass-FET pairs, SPICE)✅
M3 Toolchain (KiCad, scripted netlist pipeline)✅
M4 Verification (switch-level equivalence, vendor-model SPICE)✅
M5 Layout (placement, routing, DRC-clean, fab outputs)✅
M6 Fab & bring-up⏳

Rev A vs rev B

Rev A is what is being built. After the order was placed, a defect was found that the verification chain was structurally unable to see: the transform preserved the netlist's topology but not its device ratios. Ratioed NMOS needs a weak load against a strong pull-down; the 1,018 depletion loads correctly became 10 kΩ resistors, but the enhancement-mode VCC-side FETs kept the same BSS138W as their pull-down — a 1:1 ratio. On the eight data-bus output drivers that costs 262 mA and 0.90 W per FET (against 220 mA and ~0.3 W ratings) and leaves the logic low at 1.0–1.9 V against a 1.1–1.5 V threshold, so the stage can read high when it should read low. Measured in sim/driver_contention.sp; the corroboration is that it puts the board at ~2 A / ~10 W, which is exactly where the MOnSter 6502 has always been published.

Rev A boards are fixable by hand: 10 kΩ in series with eight FETs, all on the front face in one column. → Illustrated rework instructions — true-scale renders of all eight sites generated from the board file, the exact coordinates, the procedure and its verification steps. (Source: docs/rework-dor-series-r.html.)

Rev B fixes it in the generator. DISCRETE6502_REV_B=1 python3 tools/gen_netlist.py emits a series resistor for each VCC-side FET that has a pull-down to fight — 142 of the 164, the other 22 being unable to contend at all — sized per net from its gate load (10k where the net drives one gate, down to 100R on the 13 nF clock nets, all values already in the BOM). None of the 164 turned out to be a deliberate push-pull driver, so the 1:1 ratio error really is that uniform. The equivalence gate is green on rev B. No rev B board has been made — it needs the full pipeline re-run from placement onward, so it is a respin rather than a patch. Rev A output is byte-identical with the flag off, so the fabricated design cannot drift.

Highlights

  • Faithful dynamic NMOS logic — not a static re-design: the visual6502 netlist's 3,239 unique transistors, with the 778 bidirectional pass transistors implemented as back-to-back FET pairs (BSS138W; clock-edge bootstrap validated in SPICE with the manufacturer's model) and 1,023 pull-up resistors standing in for the depletion loads. Realistic clock ~10–20 kHz — the decode-PLA input lines drive up to 71 discrete gates behind one 10k pull-up (sim/fanout_speed.sp).
  • Machine-checked correctness: a switch-level simulator proves the transformed netlist produces bit-identical traces to the original visual6502 netlist while running real 6502 code; board-vs-netlist parity and independent copper-connectivity checks close the chain. Final DRC: zero electrical violations.
  • Reverse validation (tools/extract_netlist.py): the netlist is also read back out of the copper — every net label discarded, conductors recovered geometrically from pads, tracks, vias and zone fills — giving 0 opens and 0 shorts against the intended netlist, and a netlist that runs the 6502 test program correctly. The copper, read as copper, executes instructions. Verified to be able to fail: cutting one track reports exactly one open.
  • Custom autorouter (tools/route_nc.c/.py): a PathFinder-style negotiated-congestion router — nets route through conflicts, shared cells get iteratively penalized, conflicted nets rip-up and retry — on a 0.13 mm grid over 4 routing layers, with warm-start checkpoints. 8,421 signal connections routed; the C core does a full negotiation iteration in seconds.
  • Bring-up harness built in: an unpopulated Raspberry Pi Pico 2 W site on the back is wired to serve as clock master and memory emulator (data bus, 14 address bits with 16 KB mirroring, reset, R/W, SYNC via factory-fitted series resistors), so the intended workflow is to solder a Pico on, flash the firmware, and run programs with full bus tracing — no other computer needed. The firmware in pico-controller/ is written and builds, but is untested against hardware that does not exist yet.

Power budget

Dominated by the NMOS pull-up current, not switching. Component counts are from gen/netlist.json; the LED figure is simulated (sim/led_tap.sp).

ContributionBasisTypicalWorst case
Pull-up static current1,023 × 10 kΩ, 0.50 mA per node held low; ~half low at any moment (worst case: all)0.26 A / 1.28 W0.51 A / 2.56 W
Register LEDs55 taps × 1.42 mA; ~half the monitored bits set (worst case: all lit)0.04 A / 0.20 W0.08 A / 0.39 W
Dynamic switching109 nF total gate capacitance; 21 nF of it on clock-rate nets, rest at ~15% activity, at 10 kHz~9 mW~45 mW at 50 kHz
Pico 2 W, if VSYS is soldered~30 mA at 3.3 V through its buck0.02 A / 0.12 W0.03 A / 0.15 W
Total @ 5 V — ⚠️ incomplete, see below≈ 0.32 A / 1.6 W≈ 0.63 A / 3.2 W
Total @ 5 V, as actually builtdriver contention added≈ 2.1 A / ≈ 10.4 W

SUPERSEDED 2026-08-01 — this table is wrong by about 6x. It counts pull-up resistors, LEDs and switching only. It does not count driver contention: the eight data-bus output drivers hold a VCC-side FET and a pull-down FET on together for 47–93% of the time, drawing 262 mA each at 5 V. Measured in sim/driver_contention.sp, that adds +1.76 A and +8.8 W, taking the board to ≈2.1 A / ≈10.4 W — which is where the MOnSter 6502's published 2 A / 10 W was all along. A 1 A supply is not enough; use 3 A. Full analysis and the rework that fixes it: "Driver contention" in project-plan.md.

A 5 V / 1 A bench supply covers even the worst case. Use 3 A — see the correction above. The old comparison line read "compare the original MOnSter 6502 at ~10 W", which in hindsight was the clue: same logic, same style, and it should never have been six times cheaper. With contention counted, this board lands in the same place. The 8.8 W of contention is not spread over the 900 cm² board either — it is concentrated in eight SOT-323s in one column, which is the whole problem.

At 3.3 V (the diagnostic fallback rail — bring-up starts at 5 V, see pico-controller/README.md): ≈ 0.19 A / 0.64 W typical, 0.38 A / 1.3 W worst case. The LEDs there draw 0.67 mA each instead of 1.42 mA, because the 2.2 kΩ ballast has 1.4 V less headroom above the LED's ~1.85 V forward drop — 47% of the current, but only about 20% less perceived brightness (perception goes roughly as the cube root of luminous output): dimmer, still perfectly readable.

Transient behaviour is more interesting than the average: the cclk net alone carries 13 nF of gate load (482 gates), so clock edges pull ~50–100 mA for a microsecond or two. That is what the 96 distributed 100 nF decouplers and 4 × 10 µF bulk caps are for — they hold the rail to ~10 mV of droop across an edge.

Repository layout

  • project-plan.md — goals, milestones, decision log, current handoff (start here)
  • cards/ — deep-dive notes per topic (architecture, layout, verification, …)
  • data/visual6502/ — the reverse-engineered netlist source data
  • tools/ — the entire generation pipeline: netlist transform, die placement, power routing, the negotiated-congestion signal router, finishing passes, silkscreen, verification
  • sim/ — ngspice testbenches: pass-pair latch, 3.3 V validation, LED brightness, fanout speed
  • gen/ — generated artifacts: netlist, boards (board_routed_golden.kicad_pcb), renders, and the JLCPCB fabrication package (gen/fab/)

Regenerating the board

The full pipeline, in order (KiCad 10's bundled python for board steps):

text
python3 tools/gen_netlist.py         # visual6502 data -> netlist (+ invariant checks)
python3 tools/switchsim.py           # equivalence gate: must stay green
<kicad-python> tools/gen_pcb.py      # die-true placement, board setup
<kicad-python> tools/route_power.py  # planes + ~3,700 stitch vias
<kicad-python> tools/route_power_finish.py   # (on the presignal snapshot)
<kicad-python> tools/route_nc.py     # signal routing (hours; checkpointed)
<kicad-python> tools/fix_same_net_vias.py
<kicad-python> tools/fix_via_pairs.py
<kicad-python> tools/enlarge_vias.py  # 0.30mm drills for JLC's free class
<kicad-python> tools/add_silk.py
<kicad-python> tools/check_parity.py && tools/check_gaps.py + kicad-cli drc
<kicad-python> tools/extract_netlist.py   # rebuild the netlist from copper (LVS)
python3 tools/switchsim.py           # now also simulates the extracted netlist

See cards/layout.md for the rules and hard-won caveats behind each step.

License & attribution

Copyright © 2026 Edward Patel.

This project is licensed CC BY-NC-SA 4.0 (Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International) — the full legal code is in LICENSE. It covers everything in the repository: the board design and generated artifacts in gen/, the generation and verification tools in tools/, the SPICE testbenches in sim/, the Pico firmware in pico-controller/, and the documentation.

In short: use it, modify it and share it, with attribution, for non-commercial purposes, and share derivatives under the same terms.

The licence is inherited rather than chosen. The design's ground truth is the visual6502 project's netlist data, whose segdefs.js is itself CC BY-NC-SA, so this work carries the same terms forward. Attribution is owed to visual6502.org, which traced a real 6502 die photograph by photograph and made the result public.

The MOnSter 6502 by Eric Schlaepfer and Evil Mad Scientist Laboratories proved a discrete 6502 is possible and is gratefully acknowledged as inspiration. This is an independent design and is not affiliated with that project.

Parts

5,425
QtyValueFootprintReferences
4051BSS138KSOT-323_SC-70Q1, Q10, Q100, Q101, Q1000, Q1001, Q1002, Q1003, Q1004, Q1005, Q1006, Q1007, Q1008, Q1009, Q1010, Q1011 +4035
102310kR_0402_1005MetricR1, R10, R100, R101, R1000, R1001, R1002, R1003, R1004, R1005, R1006, R1007, R1008, R1009, R1010, R1011 +1007
96100nFC_0402_1005MetricC1, C2, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19, C20, C21, C22, C23 +80
56100pF-DNPC_0402_1005MetricC101, C102, C103, C104, C105, C106, C107, C108, C109, C110, C111, C112, C113, C114, C115, C116 +40
552.2kR_0402_1005MetricR1019, R1020, R1021, R1022, R1023, R1024, R1025, R1026, R1027, R1028, R1029, R1030, R1031, R1032, R1033, R1034 +39
55LED_REDLED_0603_1608MetricD1, D2, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, D20, D21, D22, D23 +39
261kR_0402_1005MetricR1085, R1086, R1087, R1088, R1089, R1090, R1091, R1092, R1093, R1094, R1095, R1096, R1097, R1098, R1099, R1100 +10
121N4148WSD_SOD-323D56, D57, D58, D59, D60, D61, D62, D63, D64, D65, D66, D67
6100RR_0402_1005MetricR1074, R1075, R1076, R1077, R1078, R1079
410uFC_0805_2012MetricC97, C98, C99, C100
4MountingHole_3.2mm_M3MountingHole_3.2mm_M3H1, H2, H3, H4
1AB0TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP1
1AB1TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP2
1AB10TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP11
1AB11TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP12
1AB12TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP13
1AB13TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP14
1AB14TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP15
1AB15TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP16
1AB2TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP3
1AB3TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP4
1AB4TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP5
1AB5TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP6
1AB6TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP7
1AB7TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP8
1AB8TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP9
1AB9TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP10
1CLK0TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP25
1CLK1OUTTestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP26
1CLK2OUTTestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP27
1DB0TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP17
1DB1TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP18
1DB2TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP19
1DB3TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP20
1DB4TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP21
1DB5TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP22
1DB6TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP23
1DB7TestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP24
1IRQTestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP30
1NMITestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP31
1Pico2_W_siteRaspberryPi_Pico_W_SMDU1
1RDYTestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP29
1RESTestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP28
1RWTestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP32
1SOTestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP34
1SYNCTestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP33
1VCCTestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP36
1VSSTestPoint_THTPad_4.0x4.0mm_Drill2.0mmTP35

More from epatel/discrete6502

1
  • 6 layers290.7 × 322 mmBoard routed golden, the printed circuit board in 3D

    Board routed golden

    epatel/discrete6502

    A MOS 6502 CPU rebuilt from 4,051 discrete transistors on a 291x322mm six-layer board that reproduces the original die layout

    5,425 parts14

Similar boards

  • 2 layers161 × 132 mmSparkFun BMV080 panelized, the printed circuit board in 3D

    SparkFun BMV080 panelized

    embeddedos-org/eCAD-Hardware-Products

    Hardware designs + EE docs + Board datasheets of Multiple products

    2,869 parts8MIT
  • 2 layers68.6 × 53.3 mmDreh shield, the printed circuit board in 3D

    Dreh shield

    eurovibes/dreh_shield

    An Arduino Uno R3 rotary encoder input shield

    33 partsCERN-OHL-S-2.0
  • 4 layers99.2 × 56 mmPanel AB, the printed circuit board in 3D

    Panel AB

    sastles-com/isolation-sphere-solo-xiao

    球体 LED ディスプレイのファームウェア。server なし (solo) と server あり (配信) の両方を 1 つの バイナリで動かす。

    190 parts
  • 2 layersJbc 245, the printed circuit board in 3D

    Jbc 245

    radioelf/C245-JBC-control

    Control para soldadores JBC con puntas del tipo C245

    79 parts15
  • 2 layers76.9 × 100 mmBo Tom V3, the printed circuit board in 3D

    Bo Tom V3

    Chethien1912/Shrimp-Feed-Grinder-Motor-Driver-PCB

    Board điều khiển động cơ máy xay thức ăn cho tôm

    75 parts
  • 2 layers38 × 39 mmTriac changed example, the printed circuit board in 3D

    Triac changed example

    GauravSh7/tracewise-pcb-validator

    AI-assisted PCB design validation platform for early-stage KiCad board review.

    21 parts
  • 2 layers50 × 100 mmDimmer final, the printed circuit board in 3D

    Dimmer final

    MateoCignetti/ProyectoFinal

    Esta obra está bajo una [Licencia Creative Commons Atribución-NoComercial-CompartirIgual 4.0 Internacional][cc-by-nc-sa].

    32 parts2
  • 2 layers34.3 × 32.9 mmMcu sensor firmware studies, the printed circuit board in 3D

    Mcu sensor firmware studies

    AssaadMH/mcu-sensor-firmware-studies

    A set of small but complete embedded programs — PIC instrumentation with LCD readout, and an NFC tag reader.

    7 parts1MIT

Questions

How big is the Board presignal PCB?

It measures 290.7 × 322 mm and has 6 copper layers, 1.6 mm thick.

What parts does the Board presignal use?

5,425 parts, built around the AB4, BSS138K, 1N4148WS and AB1. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Board presignal KiCad files?

From the epatel/discrete6502 repository on GitHub, at the commit this page was made from: the board is gen/board_presignal.kicad_pcb. PCBKit opens the board in the browser, with nothing to install.

Can I use the Board presignal design in my own project?

Its repository states no licence, so its author keeps all rights: ask epatel before reusing the design.