bare-metal-bringup
Use when bringing up bare-metal or kernel code on a new architecture, SoC, or board (RISC-V, ARM, x86, ESP32) and it won't boot,…
Use when loading a bitstream onto a physical FPGA and driving or observing it over JTAG or GPIO, especially bit-banged JTAG from a host like a Raspberry Pi, or when configuration silently fails
Claude Code
$ npx -y skills add lilithsemi/claude-for-hardware --skill fpga-bringup --agent claude-code
Codex
$ npx skills add lilithsemi/claude-for-hardware --skill fpga-bringup -a codex -y
Cursor
$ npx skills add lilithsemi/claude-for-hardware --skill fpga-bringup -a cursor -y
Gemini CLI
$ npx skills add lilithsemi/claude-for-hardware --skill fpga-bringup -a gemini-cli -y
GitHub Copilot
$ npx skills add lilithsemi/claude-for-hardware --skill fpga-bringup -a github-copilot -y
OpenCode
$ npx skills add lilithsemi/claude-for-hardware --skill fpga-bringup -a opencode -y
Windsurf
$ npx skills add lilithsemi/claude-for-hardware --skill fpga-bringup -a windsurf -y
name: fpga-bringup description: Use when loading a bitstream onto a physical FPGA and driving or observing it over JTAG or GPIO, especially bit-banged JTAG from a host like a Raspberry Pi, or when configuration silently fails
Bringing up an FPGA on the bench means three things: get the bitstream in over a real transport, drive the design's inputs, and observe its outputs. Most early failures are transport and pin-mapping problems, not logic problems.
**Core principle:** Bring the transport up first and prove it independently, before you trust anything the design does. A bitstream that "loaded" but didn't is the most expensive hour on the bench.
Before any design-level work, prove the link end to end:
1. **Read the IDCODE.** Shift the JTAG IDCODE instruction and confirm the value matches the part. If IDCODE is wrong or all-ones/all-zeros, you have a wiring, voltage, or clock problem. Stop here and fix it. Nothing downstream matters yet. 2. **Confirm the IR width.** The instruction register width is part-specific and must match the design's TAP. A wrong IR width shifts every instruction into garbage and configuration silently no-ops. Make the IR width a parameter, not a magic constant baked in one place. 3. **Confirm clock and levels.** TCK speed, signal voltage, pull directions. Bit-banged GPIO has no buffering; mind the levels and keep TCK slow until the link is proven.
Before you blame the bench, confirm the bitstream's configured clock is at or below the design's real Fmax. The PLL output, UART baud divisor, and timer timebase all derive from it. A bitstream configured for 48 MHz on logic that only times at 29 MHz fails with setup violations AND a wrong baud rate, which looks exactly like a wiring or transport fault. Regenerate at a clean integer PLL divide below Fmax. See `fpga-synthesis-fit`.
A dead-silent board with a clean configuration load is very often a PLL that never locked, not a logic or wiring fault. When the design gates reset on `~LOCK` (the common `sysReset = porReset | ~LOCK`), a PLL that never locks holds the core in reset forever and every output stays dead.
Check the VCO math from the emitted PLL parameters BEFORE you flash:
A second PLL whose LOCK is unconnected (a DDR PHY PLL that does not gate core reset) can carry the same divider bug silently until you bring that block up.
Before bench guessing, partition logic from analog in simulation. Generate the design with NO target (sim-passthrough clock, external reset, flop memories, no PLL or block-RAM blackboxes), dump the SystemVerilog, and run it under a fast compiled simulator (Verilator). If the design streams its output here, the LOGIC is correct and the suspect is the PLL or a primitive the flop sim does not model. An interpreted RTL sim is usually too slow for a full boot (tens of thousands of cycles to first output); a compiled sim does it in a fraction of a second after a one-time compile. Lower the clock or UART divisor to shrink the run.
To sim the REAL netlist instead of the flop stand-in, supply functional models for the vendor blackboxes. The yosys `ecp5/cells_sim.v` DP16KD is a pure stub: it declares the INITVAL params but has no read or write logic, so a real-netlist sim reads every block-RAM ROM as zero and the core hangs at instruction zero. That hang is a SIM ARTIFACT, not a hardware bug. Write a functional primitive model (unpack INITVAL per `fpga-synthesis-fit`'s `dp16kd-initval-packing.md`, clocked read and write) plus a behavioral PLL and config stub, and the real netlist runs, isolating the remaining failure to the analog PLL the stub cannot model.
When every simulation passes but the assembled design is dead on the board and you cannot observe internals, do NOT keep theorizing. Build a ladder of tiny bitstreams, each bit-banging ONE diagnostic byte out the UART pin, each isolating a single layer, from the rawest signal upward:
1. Raw-oscillator streamer (a fixed byte clocked straight off the input pin): proves the oscillator, FPGA configuration, the pin, and the host adapter. 2. PLL-lock probe (emit
Claude Code skills for hardware design, validation, and bring-up. A plugin of focused skills that teach Claude how to do real hardware work: designing reusable HDL, integrating an SoC, bringing up FPGAs and bare-metal targets, building firmware boot chains,
Use when bringing up bare-metal or kernel code on a new architecture, SoC, or board (RISC-V, ARM, x86, ESP32) and it won't boot,…
Use when building or debugging a compiler backend, codegen, or assembler and you need to prove the generated machine code is…
Use when verifying a hardware DUT (a CPU core, FPGA, or netlist) against a golden reference model, building coverage-guided…
Use when building or debugging a firmware and boot chain (RISC-V SBI, UEFI, ACPI, a bootloader handoff like Limine to an OS) or…
Use when synthesizing RTL to an FPGA with yosys/nextpnr (ECP5/Lattice and similar), fighting area or routing congestion,…
Use when writing, refactoring, or deciding how to test an HDL module, component, or IP block (ROHD, Chisel, SpinalHDL, Verilog,…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.