Skip to content

purefunsolutions/alterade2-flake

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

alterade2-flake

Nix flake for working with the Altera DE2 (Cyclone II EP2C35F672C6) on NixOS in 2026 — using Haskell Clash for the design and Quartus II 13.0sp1 Web Edition for synthesis, place-and-route, and flashing over the board's onboard USB Blaster.

Cyclone II support was dropped in Quartus II 13.1, so 13.0sp1 is the last version of any Quartus edition that can target the DE2. Since it's a 32-bit vendor blob that nixpkgs does not ship, we wrap it in an FHS environment with the 2013-era libraries it expects (libpng12, libudev.so.0 shim, 32-bit GTK/X11, etc.).

Scope: classic DE2 board only. DE2-70 and DE2-115 have different FPGAs and pin assignments — this flake will not synthesize correctly for them.

One-time setup

  1. Download Quartus II 13.0sp1 Web Edition for Linux from Altera:

    Expected sizes/hashes:

    • 4.49 GB (4,818,657,280 bytes)
    • SHA1 2b110eff0d544bcda4013e265f6feaa507482357
    • SRI sha256-2sTQP/tpxGV5YjQ/3q9cIMpxXsvwbuG8fgD+MPy860w=
  2. Pin the tarball into the local Nix store:

    nix-prefetch-url --type sha256 file://$HOME/Quartus-web-13.0.1.232-linux.tar

    That adds the file under /nix/store/…-Quartus-web-13.0.1.232-linux.tar; requireFile in pkgs/quartus-ii-13/sources.nix resolves it by the pinned hash on every subsequent build.

    Keep a backup outside any Nix GC root (e.g. ~/quartus-backup/) so you don't have to re-download if Altera ever rotates the URL.

  3. (On NixOS host) enable the USB Blaster udev rules by importing the module into your system configuration:

    # configuration.nix
    {
      inputs.alterade2-flake.url = "path:/home/mika/alterade2-flake";
      # …
      imports = [ inputs.alterade2-flake.nixosModules.usb-blaster ];
      hardware.altera-usb-blaster.enable = true;
    }

    Rebuild and reboot (or at least systemctl restart systemd-udevd).

Build commands

# Enter a dev shell with clash, clashi, quartus_sh, quartus_pgm, gtkwave, …
nix develop

# Build just the Quartus toolchain (produces bin/quartus_sh etc. under ./result)
nix build .#quartus-ii-13

# Synthesize the DE2 Blinky — Clash → Verilog → Quartus → Blinky.sof
nix build .#de2-blinky

# Flash the resulting .sof over the USB Blaster (board must be plugged in)
nix run .#flash-de2

# Reformat all .nix with alejandra + deadnix + statix
nix fmt

After nix build .#de2-blinky, the output tree contains:

result/
├── Blinky.sof               # bitstream for quartus_pgm
├── reports/
│   ├── Blinky.fit.rpt       # place-and-route summary
│   ├── Blinky.map.rpt       # synthesis summary
│   ├── Blinky.sta.rpt       # timing analysis
│   └── Blinky.asm.rpt
└── verilog/
    └── Blinky.topEntity/
        └── blinky.v         # Clash-generated Verilog

Writing your own design

Follow the shape of pkgs/de2-blinky/:

  1. YourDesign.hs — a Clash module defining topEntity plus a {-# ANN topEntity (Synthesize {...}) #-} with explicit PortNames.
  2. YourDesign.qsf — Quartus pin assignments; see Blinky.qsf for the reusable DE2 pin block (CLOCK_50, KEY[0..3], LEDR[0..17], LEDG[0..8]).
  3. YourDesign.sdc — timing constraints; create_clock -period 20.0 [get_ports CLOCK_50] at minimum.
  4. YourDesign.qpf — trivial project file with PROJECT_REVISION.
  5. A package.nix copied from pkgs/de2-blinky/package.nix with the Blinky string replaced.

Flashing: volatile vs. permanent

Target File Behaviour
FPGA SRAM .sof Loaded immediately via JTAG; lost on power cycle.
EPCS64 flash .jic Permanent; survives power cycle. Generate via quartus_cpf -c Blinky.cof.

For day-to-day development, .sof is what you want — nix run .#flash-de2 uses it. Only use .jic when you want the design to persist across reboots.

Troubleshooting

  • quartus_sh: Unable to open USB device — stale jtagd. killall jtagd and retry; the flash-de2 app does this automatically.
  • jtagd cannot find pgm_parts.txt — symlink it into place: sudo mkdir -p /etc/jtagd && sudo ln -s result/share/altera13.0sp1/quartus/linux/pgm_parts.txt /etc/jtagd/jtagd.pgm_parts.
  • Segfault on startup (quartus_sh) — known glibc ≥ 2.34 interaction; try setarch x86_64 -R quartus_sh … (disables ASLR).
  • lsusb doesn't show 09fb:6001 — USB cable / port issue, or the udev module was enabled without a udev reload. Try sudo udevadm control --reload && sudo udevadm trigger.

Layout

alterade2-flake/
├── flake.nix                       # flake-parts entrypoint
├── flake.lock
├── README.md
├── CLAUDE.md
├── nix/                            # flake-parts modules
│   ├── default.nix
│   ├── devshell.nix
│   ├── treefmt.nix
│   └── checks.nix
├── nixos-modules/
│   └── usb-blaster.nix             # hardware.altera-usb-blaster.enable
├── pkgs/
│   ├── default.nix                 # perSystem wiring
│   ├── quartus-ii-13/
│   │   ├── sources.nix             # requireFile + pinned hash
│   │   ├── unwrapped.nix           # vendor installer → $out/opt/…
│   │   ├── fhs-env.nix             # buildFHSEnv + libudev shim
│   │   └── package.nix             # bin/<tool> wrappers
│   └── de2-blinky/
│       ├── Blinky.hs               # Clash source
│       ├── Blinky.qsf              # DE2 pins
│       ├── Blinky.sdc              # timing
│       ├── Blinky.qpf              # Quartus project file
│       └── package.nix             # builds Blinky.sof
└── apps/
    └── flash-de2.nix               # nix run .#flash-de2

About

Nix flake for Altera DE2 - Cyclone II based FPGA development board

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors