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, hangs after boot, or faults…
Use when building or testing RTL in ROHD (Dart), rohd_bridge, or rohd_hcl and hitting hierarchy-violation errors, "Bad state: No element" at sim setup, co-simulation failures, SystemVerilog emission name mismatches, or unexpected register read latency
$ npx -y skills add Midstall/claude-for-hardware --skill rohd-rtl-gotchas --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/rohd-rtl-gotchasContext preview
The summary Claude sees to decide when to auto-load this skill.
Use when building or testing RTL in ROHD (Dart), rohd_bridge, or rohd_hcl and hitting hierarchy-violation errors, "Bad state: No element" at sim setup, co-simulation failures, SystemVerilog emission name mismatches, or unexpected register read latency
name: rohd-rtl-gotchas description: Use when building or testing RTL in ROHD (Dart), rohd_bridge, or rohd_hcl and hitting hierarchy-violation errors, "Bad state: No element" at sim setup, co-simulation failures, SystemVerilog emission name mismatches, or unexpected register read latency
ROHD (Rapid Open Hardware Development, Dart RTL) plus rohd_bridge and rohd_hcl have a handful of sharp edges that produce cryptic errors at build or sim setup, far from the actual cause. These are the ones that cost real hours on River and Harbor.
**Core principle:** Most of these surface as a hierarchy-rule violation or a "Bad state: No element" hang, and the fix is almost never where the error points. Match the symptom below to the cause directly instead of debugging the stack trace.
ROHD's hierarchy checker rejects wiring two sibling modules through a shared bidirectional (`inout`/`LogicNet`) net that closes a loop (a SPI controller plus a behavioral SPI-flash model sharing `spi_io`). The error reads "should only communicate via inputs/inouts" and it may even invert the hierarchy (think the DUT contains its parent).
Two distinct causes, same message:
Two instances of the same module class with different constructor params (two ROMs with different contents or widths) are different module definitions. ROHD uniquifies the name (`Foo_0`), but per-module SystemVerilog file emission can then collide or mismatch the reference ("RiverCore refs Foo, file defines Foo_0", reported as "module not part of the design").
Fix: give each a distinct stable `definitionName` plus `reserveDefinitionName: true` so the emitted file name and the instantiation agree.
When invoking yosys after `module.generateSynth()`: the top module name in the SV is the class/`definitionName`, not the instance `name`. Grep `^module` to find the real top first.
Do not read `Process.environment` (or any process global) inside a module to switch a feature, a width, or a behavior. Pass a constructor parameter or a typed config object. The environment is legitimate only at the OUTERMOST generator or CLI entry point, parsed once into that config, which then flows down as parameters.
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,
Repo: Midstall/claude-for-hardware
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, hangs after boot, or faults…
Use when building or debugging a compiler backend, codegen, or assembler and you need to prove the generated machine code is correct by executing it on a real…
Use when verifying a hardware DUT (a CPU core, FPGA, or netlist) against a golden reference model, building coverage-guided fuzzing, or detecting where silicon…
Use when building or debugging a firmware and boot chain (RISC-V SBI, UEFI, ACPI, a bootloader handoff like Limine to an OS) or adding measured boot with a…
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…
Use when synthesizing RTL to an FPGA with yosys/nextpnr (ECP5/Lattice and similar), fighting area or routing congestion, measuring Fmax, deciding why a design…