Circuit review & bench-test guide
AXO-007 — VGA output dual-PMOD module
Document purpose#
This document explains the axo-007-vga module at component level and turns the design evidence into a manual-review and bench-test plan. It is based on generate_design.py (rev 0.1-schematic, 2026-07-12), the README, the generated schematic, the ERC report in reports/erc.rpt, and the industry-standard VESA DMT timing for 640×480@60 Hz. There is no IC on this board — it is passive resistors and a DE-15 connector — so no device datasheet is consulted; the resistors are Yageo RC0603 thick-film 1 % chips and the ceramic is a Murata GRM188.
The board is an unfabricated prototype: schematic generated, ERC clean (0 errors / 0 warnings, reports/erc.rpt), netlist reviewed, no PCB layout, no fabricated board, no BOM export, no bench results. It spans two adjacent host PMODs; the J1↔J3 plug pitch must match the ECP5 host's paired-socket spacing exactly, and that pitch is a layout-stage property that does not exist yet. Every expected value below is a design target to verify, not proof that an assembled board works or is safe on a real monitor.
1. What the board does#
The board is a passive 4:4:4 RGB VGA output: three independent 4-bit binary-weighted resistor-ladder DACs convert twelve 3.3 V CMOS GPIO bits from the FPGA fabric into three analog color voltages, sums each color at its own node, and drives them — with HSYNC and VSYNC — into a DE-15 high-density ("VGA") socket for a standard analog monitor.
- Red = R1–R4, Green = R5–R8, Blue = R9–R12; each ladder is 511 Ω / 1.02 kΩ / 2.05 kΩ / 4.12 kΩ from bit 3 (MSB) to bit 0.
- Each ladder sums into the monitor's 75 Ω input termination. All bits high gives a Thevenin source Req = 511∥1020∥2050∥4120 = 272.6 Ω, Veq = 3.3 V, so full scale into 75 Ω is Vfs = 3.3 × 75/(75+272.6) = 0.711 V ≈ the 0.7 V VGA analog spec. That is 4096 displayable colors.
- HS and VS are 3.3 V CMOS through 100 Ω series resistors (R13/R14); monitors accept 3.3 V sync levels (the spec is TTL).
There is no video timing on the board itself. The FPGA's vga_timing HDL core generates the pixel clock, active-video window, and sync pulses; the board is purely the analog output stage. It has no EDID/DDC (pins 12/15 unwired), so the monitor must fall back to analog-timing auto-detection.
Functional block diagram#
PMOD A (J1) "RED/GREEN" DE-15 socket (J2)
1..4 RED3..RED0 ──> R1..R4 ┐
├─ VGA_R (node) ── pin 1 R ──> monitor 75Ω
7..10 GRN3..GRN0 ──> R5..R8 ┘
R5..R8 ──── VGA_G (node) ── pin 2 G ──> monitor 75Ω
PMOD B (J3) "BLUE/SYNC"
1..4 BLU3..BLU0 ──> R9..R12 ── VGA_B (node)─ pin 3 B ──> monitor 75Ω
7 HS ──> R13 100Ω ──────────────────────────── pin 13 HS ──> monitor sync
8 VS ──> R14 100Ω ──────────────────────────── pin 14 VS ──> monitor sync
9,10 NC
3V3 ── C1 100nF ── GND pins 5-8,10 GND + SH shield
Per color, the 4 ladder resistors meet at one summing node = that color's
DE-15 pin; the monitor's internal 75Ω to GND is the bottom of the divider.
2. Safety and scope boundaries#
- Single 3.3 V domain, no external supply. Electrical shock risk is essentially zero. The real hazards are orientation errors across two unkeyed PMOD plugs and the reverse-engineering assumption that any given monitor will lock to a slightly-off pixel clock (section 6).
- The 0.7 V analog ceiling is guaranteed by construction, not by firmware. Even with all twelve color bits driven high, the worst-case node voltage into 75 Ω is 0.711 V — the resistor ladders make it physically impossible for this board to exceed ~0.71 V on R/G/B regardless of what the HDL does. Treat this as a safety property: no software fault can over-drive an analog monitor input from this board.
- First pattern must be monitor-safe. The first bench image should be a static full-screen mid-gray or a static color-bar with correct VESA timing and correct sync polarity, held for seconds, before any fast/animated pattern. Verify sync lock and geometry first. A mistimed or wrong-polarity signal cannot damage a modern LCD, but an old CRT should never be driven with a fast changing out-of-range signal before the timing is confirmed stable.
- Sync polarity is load-bearing. 640×480@60 per VESA DMT uses negative HSync and negative VSync. If the HDL emits the wrong polarity the monitor will not lock (black screen or "out of range"). This is a firmware property the board cannot fix.
- ESD is an open item. The VGA cable is a human-handled connector. No dedicated video TVS array is fitted (section 5, section 6). Handle the cable end and the board with normal ESD care; do not treat this prototype as ESD-qualified.
- Connect an earth-referenced scope ground only to board GND / the DE-15 shell.
- Prototype operation on one monitor is not VESA, EMC, or safety certification, and says nothing about compatibility with strict scaler/HDMI-converter inputs.
3. Power and control sequence#
There is no power sequencing to speak of — the board is passive — so the "sequence" is the signal-integrity and timing order that makes an image appear.
- The host powers both PMODs from the same 3V3 rail (J1/J3 pins 6/12). C1 decouples that rail at the connector. No current of consequence flows until the HDL drives the color/sync pins.
- The FPGA's
vga_timingcore produces a pixel clock (nominally 25.175 MHz for 640×480@60; the ECP5 board's 25.000 MHz oscillator is used instead — section 6), horizontal and vertical counters, the active-video window, and the HSync/VSync pulses at negative polarity. - During active video the twelve color bits present a 4-bit code per color; each ladder sums to an analog voltage between 0 V (code 0) and 0.711 V (code 15) at the DE-15 pin, developed across the monitor's 75 Ω termination.
- During blanking the HDL must force all color bits low (0 V / black) so the monitor sees proper front/back porches; sync pulses fire inside blanking.
- The monitor auto-detects the line rate (~31.469 kHz nominal), frame rate (~60 Hz nominal), and sync polarity, locks its horizontal and vertical oscillators, and paints the raster.
Why the ladder order and the shared node matter#
All four resistors of one color meet at a single summing node (that color's DE-15 pin), and that node is loaded by one fixed 75 Ω termination. Because the resistances are in the exact ratio 1 : 2 : 4 : 8 (511 / 1.02k / 2.05k / 4.12k), each bit's contribution to the node voltage is exactly half the next higher bit — a monotonic 16-level DAC — only if all four resistors are the correct value and share the same node and the same load. Swapping two ladder resistors, or an open bit, breaks the binary weighting and shows as a non-monotonic or missing-step gray-scale on that one color.
4. Interfaces, pin maps, and plug-in verification#
4.1 PMOD pin maps (host viewpoint, all host-driven)#
| J1 (PMOD A) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Net | RED3 | RED2 | RED1 | RED0 | GND | 3V3 | GRN3 | GRN2 | GRN1 | GRN0 | GND | 3V3 |
| J3 (PMOD B) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Net | BLU3 | BLU2 | BLU1 | BLU0 | GND | 3V3 | HS | VS | NC | NC | GND | 3V3 |
Every PMOD pin is host-driven; there are no module-driven return signals (the board never talks back to the FPGA). Bit 3 is the MSB of each color nibble.
4.2 DE-15 (HD15 "VGA") socket pinout — J2#
Amphenol L77HDE15SD1CH4F, high-density DSUB-15 female. Three rows of 5.
| Pin | Net | Pin | Net | Pin | Net |
|---|---|---|---|---|---|
| 1 | RED (analog) | 6 | GND (R return) | 11 | NC |
| 2 | GREEN (analog) | 7 | GND (G return) | 12 | NC (DDC SDA — unwired) |
| 3 | BLUE (analog) | 8 | GND (B return) | 13 | HSYNC |
| 4 | NC | 9 | NC (+5 V on some cables — not fitted) | 14 | VSYNC |
| 5 | GND | 10 | GND (sync return) | 15 | NC (DDC SCL — unwired) |
| SH | Shield → GND |
- Grounds 5–8 and 10 plus the shell/shield (SH) all tie to board GND. In a proper VGA cable each color has its own coax with pin 6/7/8 as the paired return — the per-color ground pins matter for return-current integrity even though they are all one net here.
- Pins 12/15 (DDC/EDID) are deliberately unwired. The monitor gets no EDID and must auto-detect timing. This is a documented limitation, not a fault; it means the board cannot be identified by the monitor and relies entirely on the analog sync-tracking path.
- Pin 9 (+5 V DDC power on some hosts) is not fitted — the board sources nothing on pin 9.
4.3 Dual-PMOD and DE-15 orientation / plug-in verification (read before first power)#
Mandatory section. This board has three orientation-sensitive interfaces: two unkeyed PMOD plugs whose relative pitch must match the host, and the DE-15 (which is mechanically keyed, so its own orientation is safe, but its wiring must be buzzed out once).
- J1↔J3 paired-PMOD pitch (layout-stage, currently unverified). The two 6×2 PMOD plugs must land on two adjacent host PMOD sockets simultaneously. Standard PMOD spacing is 0.9" (22.86 mm) between adjacent socket centerlines — the same constraint the camera carrier (axs-050) and 7-seg (axo-002) modules carry. Until the PCB is laid out and the plug centers are dimensioned against the specific ECP5 host's paired-socket spacing, treat "both plugs seat fully at the same time" as an unproven claim. Dry-fit both plugs before any power; if one plug seats and the other is proud, stop — do not force, and do not power a half-seated pair (bent pins short adjacent signals).
- Pin-1 orientation of each plug. PMOD plugs are not keyed against 180° rotation. Confirm J1 pin 1 and J3 pin 1 against the host silkscreen (Pmod spec 1.2 pin-1 corner; the family recipe is in
pmod-common/PMOD-SPEC-NOTES.md). A rotated plug puts 3V3 on what should be the top color bits and GND on others — invisible to ERC, obvious as a dead or wrong-color channel. - Which PMOD is which. J1 = RED/GREEN, J3 = BLUE/SYNC. Swapping the two plugs at the host (plugging J1 into the socket meant for J3) sends the sync bits to color ladders and the blue bits to nowhere — no sync lock at all. Mark the two plugs RED/GREEN and BLUE/SYNC physically.
- DE-15 wiring buzz-out (board unpowered). Buzz DE-15 pin 1 to the VGA_R node (through R1–R4), pin 2 to VGA_G (R5–R8), pin 3 to VGA_B (R9–R12), pin 13 to the R13 output, pin 14 to the R14 output. Confirm pins 5,6,7,8,10 and the shell SH are all continuous to GND, and that pins 4,9,11,12,15 are open (no EDID, no stray shorts). Confirm the shell is bonded to GND and not floating.
- Only after 1–4 pass, plug into the host and connect a monitor with a known-good VGA cable.
5. Component-by-component review#
Every reference designator in generate_design.py appears below. #FLG01 and #FLG02 are ERC power-flag pseudo-components (3V3 and GND); they have no footprint and are listed only for completeness.
5.1 Connectors#
| Ref. | Part / value | Function and why needed | If absent/open | If shorted, wrong, or misassembled |
|---|---|---|---|---|
| J1 | 6×2 right-angle PMOD plug "PMOD A: RED/GREEN" | Carries RED3..RED0 (pins 1-4) and GRN3..GRN0 (pins 7-10) plus GND/3V3 from the host | No red or green data reaches the ladders — both channels dark | 180° rotation puts 3V3/GND on color bits (wrong or dead channel); after layout, the J1↔J3 spacing must match the host paired-PMOD pitch (README release item) |
| J3 | 6×2 right-angle PMOD plug "PMOD B: BLUE/SYNC" | Carries BLU3..BLU0 (pins 1-4), HS (pin 7), VS (pin 8); pins 9/10 NC, plus GND/3V3 | No blue data and no sync — monitor never locks | Rotation or swapping J1/J3 sends sync to color nodes; HS on pin 7 / VS on pin 8 must land on ordinary GPIO (no clock-pin requirement, they are ~31 kHz / 60 Hz) |
| J2 | Amphenol L77HDE15SD1CH4F, DE-15 HD female (right-angle, housed, mounting holes) | The VGA output socket: R/G/B analog on pins 1/2/3, HS/VS on 13/14, grounds on 5-8/10, shield SH→GND | No output at all | A color-pin-to-ground short kills that color; a color-to-color short mixes channels; shell not bonded to GND leaves the shield floating (EMC/ESD path lost); DDC pins 12/15 must stay unwired (no EDID by design) |
5.2 RED ladder DAC (summing node = VGA_R = DE-15 pin 1)#
| Ref. | Value / part | Bit | Function | If absent/open | If shorted / wrong value |
|---|---|---|---|---|---|
| R1 | 511 Ω, Yageo RC0603FR-07511RL, 1 % | 3 (MSB) | Largest current contribution: half of full scale (~0.36 V step) | Red loses its top bit — max red ≈ 0.35 V, gray-scale collapses to lower half | Short to node forces red high whenever driven; wrong value skews all red levels and breaks binary weighting |
| R2 | 1.02 kΩ, RC0603FR-071K02L, 1 % | 2 | Quarter-scale contribution (~0.18 V step) | Missing bit-2 step; non-monotonic red ramp | Wrong value mis-weights red midtones |
| R3 | 2.05 kΩ, RC0603FR-072K05L, 1 % | 1 | Eighth-scale (~0.09 V step) | Missing bit-1 step | Wrong value mis-weights red |
| R4 | 4.12 kΩ, RC0603FR-074K12L, 1 % | 0 (LSB) | One LSB ≈ 47 mV at the node | Red LSB dead — 15 levels instead of 16, no fine detail | Wrong value shifts the LSB; short forces a small red offset |
5.3 GREEN ladder DAC (summing node = VGA_G = DE-15 pin 2)#
| Ref. | Value / part | Bit | Function | If absent/open | If shorted / wrong value |
|---|---|---|---|---|---|
| R5 | 511 Ω, RC0603FR-07511RL, 1 % | 3 (MSB) | Green half-scale | Green top bit lost — brightness/gray-balance shifts strongly (eye is most sensitive to green) | Short forces green high; wrong value unbalances gray toward/away from green |
| R6 | 1.02 kΩ, RC0603FR-071K02L, 1 % | 2 | Green quarter-scale | Missing green bit-2 step | Wrong value mis-weights green |
| R7 | 2.05 kΩ, RC0603FR-072K05L, 1 % | 1 | Green eighth-scale | Missing green bit-1 step | Wrong value mis-weights green |
| R8 | 4.12 kΩ, RC0603FR-074K12L, 1 % | 0 (LSB) | Green LSB ≈ 47 mV | Green LSB dead | Wrong value shifts green LSB |
5.4 BLUE ladder DAC (summing node = VGA_B = DE-15 pin 3)#
| Ref. | Value / part | Bit | Function | If absent/open | If shorted / wrong value |
|---|---|---|---|---|---|
| R9 | 511 Ω, RC0603FR-07511RL, 1 % | 3 (MSB) | Blue half-scale | Blue top bit lost — yellow cast on whites | Short forces blue high; wrong value unbalances gray toward/away from blue |
| R10 | 1.02 kΩ, RC0603FR-071K02L, 1 % | 2 | Blue quarter-scale | Missing blue bit-2 step | Wrong value mis-weights blue |
| R11 | 2.05 kΩ, RC0603FR-072K05L, 1 % | 1 | Blue eighth-scale | Missing blue bit-1 step | Wrong value mis-weights blue |
| R12 | 4.12 kΩ, RC0603FR-074K12L, 1 % | 0 (LSB) | Blue LSB ≈ 47 mV | Blue LSB dead | Wrong value shifts blue LSB |
Gray-scale/color-balance dependency: the three ladders must match each other closely, not just internally. Because a neutral gray requires R = G = B at every code, a 1 % tolerance mismatch between, say, R1 and R5 tints the gray axis. This is why all three MSBs are the same 511 Ω part number and why the per-color resistance verification (section 9.A) checks each ladder independently and against the other two.
5.5 Sync series resistors, decoupling, and ERC flags#
| Ref. | Value / part | Function and why needed | If absent/open | If shorted / wrong value |
|---|---|---|---|---|
| R13 | 100 Ω, RC0603FR-07100RL, 1 % | HSYNC series resistor: edge-rate control and short-circuit current limit into the cable, on the 3.3 V CMOS HS line | Open: no HSync reaches the monitor — no horizontal lock, "out of range"/black | Short: HS driven direct (works but no edge/short protection); much larger value + cable capacitance rounds the sync edge |
| R14 | 100 Ω, RC0603FR-07100RL, 1 % | VSYNC series resistor, same role on VS | Open: no VSync — no vertical lock, rolling/blank | Same as R13 for the vertical sync |
| C1 | 100 nF 16 V X7R, Murata GRM188R71C104KA01D | Local decoupling of the 3V3 rail at the connector; steadies the rail against the twelve color bits switching during active video | More rail bounce/SSO noise coupling into the analog nodes (subtle color noise) | Short kills the 3V3 rail (host current limit should catch it) |
| #FLG01 | ERC power flag on 3V3 | Schematic ERC bookkeeping only — declares 3V3 as a driven power net | ERC power-input warning | Not applicable — no physical part |
| #FLG02 | ERC power flag on GND | Same for GND | ERC warning | Not applicable |
Note there is no video TVS/ESD array in the BOM — deliberately, because no stock 6-channel 75 Ω-video TVS part exists in the KiCad libraries used here. See section 6 for the honest ESD budget and the deferred layout-stage part pick.
6. Standard summary and design interpretation#
No device datasheet applies (passive board). The authoritative reference is the VESA Discrete Monitor Timing (DMT) definition of 640×480@60 Hz, plus the analog VGA (RS-343-class) 0.7 V / 75 Ω video convention and the Yageo RC0603 / Murata GRM component families.
| Fact used here | Value | Board-specific interpretation |
|---|---|---|
| 640×480@60 pixel clock | 25.175 MHz (VESA DMT) | The ECP5 board oscillator is 25.000 MHz — see the clock-error row below |
| Horizontal line rate | 31.469 kHz nominal | Follows the pixel clock; 800 total pixel-clocks per line (640 active + 160 blanking) |
| Frame rate | 59.94 Hz nominal | 525 total lines per frame (480 active + 45 blanking) |
| HSync polarity | Negative | The HDL must emit active-low HSync or the monitor will not lock |
| VSync polarity | Negative | Same — both syncs are negative for this mode |
| Analog full scale | 0.7 V into 75 Ω | The ladder delivers 0.711 V — 1.6 % high, below visible/perceptible and well within monitor black/white-level tolerance |
| Sync levels | TTL (monitors accept 3.3 V CMOS) | HS/VS at 3.3 V through 100 Ω are safely inside what monitors accept |
Per-color full-scale derivation (the core of the design). With all four bits of one color driven to 3.3 V, the four ladder resistors form a Thevenin source into the monitor's 75 Ω:
- Req = 511 ∥ 1020 ∥ 2050 ∥ 4120 = 272.6 Ω, Veq = 3.3 V.
- Vfs = 3.3 × 75 / (75 + 272.6) = 0.711 V ≈ 0.7 V spec (1.6 % high).
- One LSB = 0.711 / 15 = 47 mV. Each higher bit contributes exactly ×2 the next lower one because all four resistors share the same summing node and the same 75 Ω load — the ×2 weighting is a property of the 1:2:4:8 resistance ratio, not of any active buffering.
- Caveat: the real full scale depends on the FPGA's actual output-high voltage (may be slightly below 3.3 V, and has non-zero output impedance in series with each 511/1.02k/2.05k/4.12k resistor) and on the monitor's actual termination (nominally 75 Ω, but real inputs vary). Measure the true full scale on the bench; do not assume exactly 0.711 V.
The 25.000 vs 25.175 MHz clock error. The mode wants 25.175 MHz; the board has 25.000 MHz. That is (25.175 − 25.000)/25.175 = 0.695 % low. Everything scales down by that fraction: pixel clock, so line rate ≈ 31.469 × 0.99305 ≈ 31.25 kHz, and frame rate ≈ 59.94 × 0.99305 ≈ 59.5 Hz. Analog CRTs and most LCD scalers track the incoming sync frequencies within a few percent, so a 0.7 % error is comfortably inside stock-monitor lock range and this is how countless FPGA VGA projects run. But it is not guaranteed for every display: some strict fixed-frequency scalers, capture cards, or HDMI-converter chips reject anything not matching an exact DMT entry. Treat "does this monitor lock?" as a per-display bench item (section 9.B), not a settled fact. If a target display rejects it, the fix is a real 25.175 MHz clock (PLL synthesis in the ECP5) — a host-side change, not a board change.
ESD honesty. The VGA cable is a human-handled connector, so ESD strikes on the connector shell/pins are realistic. The protection budget is:
- the ladder's series resistance — ≥272.6 Ω (and ≥511 Ω on any single bit) between any DE-15 color pin and the corresponding FPGA output;
- the host PMOD socket's own 200 Ω series resistance plus the ECP5 I/O clamp diodes (per Pmod spec 1.2.0 and the ECP5 bank structure);
- the shell/shield tied to GND.
There is no dedicated video TVS array fitted — no stock 6-channel 75 Ω low-capacitance video-TVS part exists in the KiCad libraries used to generate this design, so a proper video ESD array is deferred to a layout-stage part pick and recorded as an open item. Do not claim ESD immunity for this revision.
7. Expected values before bench testing#
All values assume a nominal 3.300 V rail, an ideal 75 Ω monitor termination, and 1 % resistors. They are design targets, not measurements.
| Quantity | Design target / calculated | What to measure |
|---|---|---|
| 3V3 at J1/J3 pin 6 | 3.30 V | DMM |
| Board current | negligible (µA-to-low-mA; passive ladders only draw through 75 Ω when driven) | Host rail delta |
| RED MSB (R1) resistance | 511 Ω ±1 % | DMM, board unplugged |
| RED bits R2/R3/R4 | 1.02 k / 2.05 k / 4.12 k ±1 % | DMM |
| GREEN ladder R5–R8 | 511 Ω / 1.02 k / 2.05 k / 4.12 k | DMM |
| BLUE ladder R9–R12 | 511 Ω / 1.02 k / 2.05 k / 4.12 k | DMM |
| Ladder Thevenin Req (all bits high, one color) | 272.6 Ω | Compute from the four measured values, or measure node-to-3V3 with all bits high |
| R13 / R14 (HS/VS series) | 100 Ω ±1 % each | DMM |
| Per-color full scale (code 15) into 75 Ω | 0.711 V (≈0.7 V spec) | Scope/DMM at DE-15 pin 1/2/3 with a 75 Ω terminator, all bits of that color high |
| One LSB step | 47 mV | Node voltage difference between code n and n+1 |
| Per-bit contributions (into 75 Ω, one bit at a time) | bit3 ≈ 0.36 V, bit2 ≈ 0.18 V, bit1 ≈ 0.09 V, bit0 ≈ 0.047 V (each ×2 the last) | Node voltage per single-bit test |
| HSync line rate | ~31.25 kHz (0.7 % low vs 31.469 kHz DMT) | Scope/counter at DE-15 pin 13 |
| VSync frame rate | ~59.5 Hz (0.7 % low vs 59.94 Hz) | Scope/counter at DE-15 pin 14 |
| HS/VS polarity | Both negative (active-low) | Scope: idle high, pulse low |
| HS/VS high level | 3.3 V CMOS (through R13/R14) | Scope at DE-15 pins 13/14 |
8. Manual schematic and assembly review checklist#
- Measure each ladder resistor before connecting a monitor: R1–R4, R5–R8, R9–R12 against 511 / 1.02k / 2.05k / 4.12k; R13/R14 = 100 Ω. Confirm no two ladder positions are swapped (a swap breaks binary weighting silently).
- Confirm all three MSB positions (R1, R5, R9) are the same 511 Ω part and all three LSB positions (R4, R8, R12) are the same 4.12 kΩ part — cross-color mismatch tints the gray axis.
- Complete section 4.3: J1/J3 pin-1 orientation, RED/GREEN vs BLUE/SYNC plug labelling, and the DE-15 buzz-out (pins 1/2/3 → color nodes, 13/14 → sync, 5-8/10/SH → GND, 4/9/11/12/15 open).
- Confirm C1 is 100 nF across 3V3/GND at the connector and not shorting the rail.
- Confirm the DE-15 shell/shield is bonded to GND (single-point at the connector) and that DDC pins 12/15 are unwired (no EDID by design).
- After layout (not started): ladder resistors placed tight at the DE-15; R/G/B traces kept short and roughly 75 Ω-disciplined; the two PMOD plugs dimensioned to the host's 0.9" paired-socket pitch; sync traces away from the color nodes; C1 at the connector power pins; a video ESD array footprint added when the part is picked.
- Plan the FPGA side:
vga_timingproducing 640×480 with negative HS and VS, all color bits forced to 0 during blanking, and — if a strict target display is required — a 25.175 MHz PLL instead of the 25.000 MHz oscillator.
9. Ordered bench-test procedure#
Stop at the first abnormal result. Record board serial, host identity, monitor make/model, cable, the measured 3V3 rail, and every ladder resistor value. Two contexts are covered: PMOD-host (plugged into the ECP5 with the HDL running) and standalone 3.3 V bench (drive the color/sync pins from a bench 3.3 V source or pattern generator, no FPGA).
A. Unpowered inspection and per-color resistance verification#
- Board unplugged from everything. Inspect under magnification; complete the section 8 checklist.
- Measure every ladder resistor end-to-end and record: R1–R4 (RED), R5–R8 (GREEN), R9–R12 (BLUE) against 511 / 1.02k / 2.05k / 4.12k, and R13/R14 = 100 Ω.
- Compute per-bit contribution for each color from the measured resistances: for a single bit i with resistance Ri driven to 3.3 V into 75 Ω, node = 3.3 × 75/(75+Ri). Confirm each bit is ≈½ the next higher bit and that the four sum (via Thevenin) to ≈0.711 V. Do this independently for all three colors — the three ladders must match each other so gray stays neutral.
- Buzz DE-15 pin 1 → VGA_R node, pin 2 → VGA_G, pin 3 → VGA_B, 13 → R13 out, 14 → R14 out; confirm pins 5-8/10/SH continuous to GND and 4/9/11/12/15 open.
- Resistance from each color node to GND and to 3V3 in both meter polarities — investigate any hard short before applying signals.
B. First power / first image (monitor-safe)#
PMOD-host context. Load vga_timing for 640×480@60 with negative HS/VS and a first pattern of static full-screen mid-gray (all three colors at code 8) or a static color-bar. Plug both PMODs (verify the pair seats together — section 4.3), connect a known-good monitor with a known-good VGA cable, power on.
- Confirm the monitor locks (reports ~640×480@~60 or simply shows a stable raster). If it shows "out of range" or stays black, go to section 10 — suspect sync polarity first, then the 25.000 MHz clock margin on that display.
- Verify geometry: full-screen fill, no rolling (vertical lock), no tearing/ pulling (horizontal lock), correct aspect. Hold the static pattern for several seconds and confirm stability before any animation.
- Scope DE-15 pin 13 (HSync): ~31.25 kHz, idle-high/pulse-low (negative). Pin 14 (VSync): ~59.5 Hz, negative. Record actual frequencies against section 7.
- Scope each color pin (1/2/3) at code 8: expect roughly mid-scale (~0.35 V) into the monitor's termination. Confirm none exceeds ~0.71 V at code 15 — the ladder guarantees this, so a reading above ~0.72 V means a wrong resistor or a short, not a firmware bug.
Standalone 3.3 V bench context (no FPGA). Drive the color/sync PMOD pins from a bench 3.3 V source or a slow pattern generator; terminate each color pin with a 75 Ω resistor to GND (emulating the monitor) if no monitor is used.
- Drive one color's four bits high one at a time; measure the node per step 3 of section A and confirm the ×2 progression and the 0.711 V all-high full scale on the real hardware.
- Drive HS and VS from a 3.3 V square-wave source; confirm 3.3 V levels at DE-15 pins 13/14 through R13/R14 and that the series resistors do not round the edge excessively into the cable capacitance.
C. Color and gray-scale correctness#
- Display a per-channel ramp (0→15 on one color, others at 0). Each of R, G, B in turn should sweep smoothly from black to full color with no missing or reversed steps — a missing step points at an open ladder bit (section 10).
- Display a gray ramp (R=G=B, 0→15). Steps must be neutral gray with no color tint; a tint at some codes means a cross-color resistor mismatch (e.g. R1 vs R5 vs R9 tolerance) or one channel's bit open.
- Display full-screen primaries and secondaries (R, G, B, cyan, magenta, yellow, white, black). White must be neutral at ~0.711 V on all three; any cast identifies the deviating channel.
- Only after static patterns pass, run an animated pattern (moving bars, Pong). Confirm no new sync instability appears under fast switching (SSO on the twelve color bits stressing the 3V3 rail / C1).
D. Timing-margin and display-compatibility survey#
- Repeat section B step 1 on several different monitors/scalers if available (old CRT, LCD, a USB VGA capture dongle, an active VGA→HDMI converter). Record which lock and which reject — this characterizes the 0.7 % clock error's real-world margin.
- If a required target display rejects the 25.000 MHz timing, re-test with a 25.175 MHz PLL-synthesized pixel clock (host-side change) and record the before/after.
- Confirm sync-polarity sensitivity: deliberately flip HS/VS to positive in the HDL and confirm the monitor loses lock (proves the negative-polarity requirement empirically), then restore negative.
E. Release-only / deferred#
- Video ESD immunity: cannot be claimed until the layout-stage video-TVS array is picked, fitted, and tested. Record as open.
- EMC (radiated emissions from the analog video and the two PMOD ribbons), long-cable signal integrity, and multi-monitor interoperability are lab-plan items beyond the first article.
10. Troubleshooting map#
| Symptom | First measurements | Likely areas |
|---|---|---|
| Monitor black / "out of range" | HS/VS polarity and frequency at pins 13/14 | Wrong (positive) sync polarity in HDL; or strict display rejecting 25.000 MHz timing; or R13/R14 open |
| No horizontal lock, vertical OK | HSync at pin 13 | R13 open, HS bit not routed, HS on wrong PMOD pin |
| Rolling / no vertical lock | VSync at pin 14 | R14 open, VS bit not routed, frame timing wrong |
| Whole image one wrong color / very dark | Which color node reads at code 15 | Rotated PMOD plug, swapped J1/J3, or that color's MSB (R1/R5/R9) open |
| One color missing entirely | Node voltage on that color pin | Open ladder / DE-15 pin, or that PMOD nibble not driven |
| Gray shows a color tint | Compare R/G/B node voltages at equal codes | Cross-color resistor mismatch, or one channel bit open |
| Missing/reversed step in one color ramp | Per-bit node voltages (section 9.A step 3) | Open or swapped ladder resistor on that bit |
| Full scale > 0.72 V on a color | Node voltage at code 15, that ladder's resistors | Wrong (too-low) resistor value or a bit shorted to node — not a firmware fault |
| Faint color noise / shimmer | 3V3 ripple at C1 during active video | C1 missing/ineffective, host rail droop under SSO |
| Locks on one monitor, not another | Line/frame rate vs that display's range | 0.7 % clock error at the edge of that scaler's tolerance — needs 25.175 MHz PLL |
| No output at all, syncs fine | DE-15 buzz-out, plug seating | Half-seated PMOD pair, DE-15 color pins open |
11. Bench record template#
| Field | Record |
|---|---|
| Board revision / serial | |
| Host context (PMOD FPGA / standalone bench) and IDs | |
| Monitor(s)/scaler(s) make, model, native mode | |
| VGA cable identity | |
| Measured 3V3 rail | |
| RED ladder R1–R4 measured | |
| GREEN ladder R5–R8 measured | |
| BLUE ladder R9–R12 measured | |
| R13 / R14 measured | |
| DE-15 buzz-out + shield-to-GND result | |
| PMOD J1/J3 orientation + pitch-seating result | |
| Monitor lock result + measured HS/VS freq and polarity | |
| Per-color full scale (code 15) into 75 Ω | |
| Per-bit ×2 progression check (all three colors) | |
| Gray-ramp neutrality result | |
| Multi-display compatibility survey (which lock/reject) | |
| ESD array status (deferred) | |
| Deviations, photos, raw-file paths | |
| Reviewer / date / disposition |
12. Review conclusion#
The design is a faithful, minimal 4:4:4 VGA output: three matched 4-bit binary-weighted ladders (511/1.02k/2.05k/4.12k) summing into the monitor's 75 Ω to produce a 0.711 V full scale that sits 1.6 % above the 0.7 V VGA spec — inside monitor tolerance — with 47 mV LSBs and a ×2 weighting that holds only because each color's four resistors share one node and one load. HS/VS pass through 100 Ω series resistors at 3.3 V CMOS, which monitors accept. The resistor ladders make the 0.7 V analog ceiling a physical guarantee: no firmware fault can over-drive the monitor's inputs from this board — the single most reassuring property for a bring-up that will be tried against real displays.
The principal open items are all honest and recorded: (1) the design is unfabricated — no layout, no board, no BOM, no bench evidence, so every value here is calculated; (2) the J1↔J3 paired-PMOD pitch must match the host's 0.9" socket spacing and is unverified until layout; (3) the 25.000 MHz oscillator is 0.695 % below the 25.175 MHz DMT pixel clock — fine for stock analog monitors, not guaranteed for strict scalers, and a per-display bench item; (4) HS/VS must be negative polarity from the HDL or nothing locks — a firmware property the board cannot enforce; and (5) no dedicated video ESD array is fitted, leaving the ladder's ≥273 Ω plus the host PMOD's 200 Ω + clamps as the whole ESD budget until a layout-stage TVS part is picked. None of these is a design defect; each is a labelled thing to verify before this module can be called released.