{ description = "FPGA flake, running verilog on ice40"; inputs = { flake-utils.url = "github:numtide/flake-utils"; }; outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (sys: let pkgs = nixpkgs.legacyPackages.${sys}; verilator = import ./verilator.nix pkgs ; yosys = pkgs.yosys; vflags = ''-DSIMULATE -Wno-fatal -Wpedantic -Wwarn-lint -Wwarn-style -Wno-PINCONNECTEMPTY -Wno-BLKSEQ -CFLAGS "-Wpedantic -std=c++20"''; verilate-src = cmd: '' cp -r ${./src} ./src cp -r ${./simulation} ./simulation find ./src/ -name '*.v' -exec ${verilator}/bin/verilator ${vflags} ${cmd} {} + ''; lint = pkgs.runCommand "lint" {} '' ${verilate-src "--lint-only"} echo "compiler didn't get angry :3" : 3 > $out ''; test-trace = pkgs.runCommandCC "test-trace" {} '' set -e ${verilate-src "--cc --build --exe --trace -CFLAGS -DTRACE=1 ./simulation/test_led.cpp -top top"} mv obj_dir "$out" && mkdir "$out/bin" cp "$out/Vtop" "$out/bin/sim" $out/bin/sim $out/trace.vcd echo "${pkgs.gtkwave}/bin/gtkwave $out/trace.vcd" > $out/bin/test-trace chmod u+x $out/bin/test-trace ''; synth = pkgs.runCommandCC "synth" {} '' mkdir -p "$out" find ${./src} -name '*.v' -exec ${yosys}/bin/yosys -f ' -sv' -q -p "synth_ice40 -top top -json $out/synth.json" {} + ''; pnr-interactive = pkgs.writeScriptBin "pnr-interactive" '' ${pkgs.nextpnrWithGui}/bin/nextpnr-ice40 --up5k --package sg48 --pcf ${./pins.pcf} --json ${synth}/synth.json --gui ''; pnr = pkgs.runCommandCC "pnr" {} '' mkdir -p "$out" ${pkgs.nextpnrWithGui}/bin/nextpnr-ice40 --up5k --package sg48 --pcf ${./pins.pcf} --json ${synth}/synth.json --asc "$out/pnr.asc" \ --freq 50 ''; flash = pkgs.writeScriptBin "flash" '' set -e bin="$(mktemp)" ${pkgs.icestorm}/bin/icepack ${pnr}/pnr.asc "$bin" ${pkgs.icestorm}/bin/iceprog "$bin" ''; deps = [ yosys pkgs.nextpnrWithGui pkgs.icestorm verilator pkgs.gtkwave pkgs.picocom ]; in rec { packages.verilator = verilator; packages.lint = lint; packages.test-trace = test-trace; packages.synth = synth; packages.pnr-interactive = pnr-interactive; packages.pnr = pnr; packages.flash = flash; devShells.default = pkgs.mkShell { packages = deps; }; } ); }