Skip to content

Releases: bubblebabyboi/sigil

Sigil 2026-10-22: whole SoC on AWS F2 (public AFI) + whole-SoC nangate45 GDS

Choose a tag to compare

The whole Sigil SoC — the in-house RV64GCV core (vector unit, L1 caches) plus the crypto/hash engine and peripherals — running on a real AWS F2 FPGA from a public AFI, and placed and routed to a GDS on nangate45.

Run it on your own F2

Public AFI agfi-035116450e0a0d093 (AFI afi-019aabf5d4a815ae5, us-east-1, Small Shell 0x10212415, PCI 0x1D0F:0xF054), core clock 62.5 MHz (interim; 100 MHz is #53).

# on an f2.6xlarge (FPGA Developer AMI, us-east-1)
git clone -b v2.3.5 https://github.com/aws/aws-fpga ~/aws-fpga && (cd ~/aws-fpga && source sdk_setup.sh)
sudo fpga-load-local-image -S 0 -I agfi-035116450e0a0d093 -H
git clone https://github.com/bubblebabyboi/sigil ~/sigil && cd ~/sigil
make -C fpga/host SDK_DIR=$HOME/aws-fpga/sdk
sudo fpga/host/sigil_host --ignore-mem-err --bin hello.bin      # any program linked at 0x8000_0000

Write your own programs with the SDK: docs/PROGRAMMING.md. Full F2 guide: docs/FPGA_F2.md.

Proven on F2 hardware (measured 62.5 MHz)

Program Result
Hello world + all 7 SDK examples (timer IRQs, SHA-256 engine, SHA-512/SHA3 streaming, Ed25519, RVV vector, FP) SIGIL TEST PASS
secp256k1 ECDSA verify + tamper reject SOC CRYPTO PASS in 0.44 s
Ed25519 (RFC 8032 TEST 1/2) + tampered / non-canonical rejects SOC CRYPTO PASS in 0.46 s
512 KiB DDR4 memory test + UART input from the host FPGA SMOKE PASS
OpenSBI v1.9 HELLO FROM S-MODE
Linux 6.6 boots to userspace (init: userspace alive, uname riscv64)

FPGA build: Vivado 2025.2, aws-fpga v2.3.5, commit 4058108, no negative slack at 62.5 MHz; 122k LUTs (9.4% of the VU47P) for the full CL, 79k for the SoC.

Whole-SoC GDS — nangate45

sigil_soc_top through the full OpenROAD-flow-scripts flow (15 SRAM macros):

Setup at 10 ns (100 MHz) met, worst slack +0.74 ns, TNS 0 — fmax 107.9 MHz
Hold met
Route DRC (OpenROAD) 0
Antenna (OpenROAD ANT) 0 net / 0 pin
Power-grid connectivity clean
Die / std-cell area 2,020 × 2,020 µm (4.08 mm²) / 0.934 mm², 23 % utilization
Power (estimate) 0.129 W

KLayout make drc with the FreePDK45 deck additionally reports 179 markers (176 antenna per that deck's model, 2 WELL.4, 1 METAL1.5 inside library cell OAI221_X4) that OpenROAD's own checks do not flag; earlier releases reported only the OpenROAD checks. Details: soc-pnr-nangate45-11-2026-10-21/summary.log.

GDS generated / place-and-route complete — not taped out. nangate45 is an open research PDK. The sky130 (Caravel-sized) implementation is in progress with a hierarchical flow (#11) and will ship in its own release.

Assets

File What
sigil_soc_top_nangate45_6_final.gds.gz nangate45 whole-SoC GDS (gunzip → 442 MB; sha256 of the .gds dd7b3b6d…dfab)
sigil_f2_cl_dcp_4058108.Developer_CL.tar unencrypted F2 design checkpoint the public AFI was created from — rebuild or modify it yourself
sigil_programs_2026-10-22.tar.gz prebuilt firmware (crypto, Ed25519, hash, smoke) and the 7 SDK example binaries
sigil_evidence_2026-10-22.tar.gz nangate45 reports, Vivado F0/CL reports, every F2 host log and UART capture (incl. the Linux boot)
SHA256SUMS checksums of the above

Known issues

  • #62 — the first AFI sets a sticky AXI error flag early in every run without affecting results; use sigil_host --ignore-mem-err.
  • #63 — the virtual UART can drop characters during bursty Linux console output.
  • #64 — the Linux payloads used for the F2 boot predate the rename (marker, DTB, 10 MHz timebase); Sigil-built payloads will follow.
  • The crypto engine has not had a side-channel or fault-injection review — do not use real keys.

Sigil: Debian 13 on AWS F2 — 64 GiB DDR4 + 16 GiB HBM (2026-10-22)

Choose a tag to compare

The whole Sigil SoC — the in-house RV64GCV core (vector unit, L1 caches) plus the crypto/hash engine and peripherals — now boots Debian 13 "trixie" with gcc and glibc on a real AWS F2 FPGA, with all of the board's memory: 48 GiB DDR4 as NUMA node 0, 16 GiB HBM as NUMA node 1, and a 16 GiB DDR4 window as the root disk /dev/pmem0. On an f2.6xlarge it reaches the login prompt 5 min 48 s after the SoC starts and passes 22/22 acceptance checks. New public AFI, Sigil-built OpenSBI v1.9 + Linux 6.12 LTS payloads, and a ready-to-boot Debian image.

The first Debian boots on the F2 found a bug in the core: a data-TLB miss that preempted an instruction-fetch page walk could take that walk's page-table response as its own: a page fault on a valid address, or wrong data without a trap. It made the kernel oops (#74). The race is in every earlier Sigil core, including the first public AFI agfi-035116450e0a0d093 and the sigil-soc-2026-10-22 release. It needs address translation, so bare-metal M-mode programs are not affected. The new AFI has the fix, plus an atomic Svadu A/D-bit update found in the same review.

Boot Debian on your own F2

Public AFI agfi-0c8aa56fde1a48495 (AFI afi-059766f9a85c6d39a, us-east-1, Small Shell 0x10212415, PCI 0x1D0F:0xF054), core clock 62.5 MHz (interim; 100 MHz is #53), HBM AXI 250 MHz. It supersedes agfi-0a1fd54ef68bdc754 (afi-035809e576d7ea8d5), whose core has the walker race: do not use that one for Linux.

# on a new f2.6xlarge (FPGA Developer AMI, us-east-1), logged in as ubuntu
curl -fsSL https://raw.githubusercontent.com/bubblebabyboi/sigil/main/fpga/scripts/f2_playground_setup.sh | bash
tmux                  # recommended: keeps the session alive if SSH drops
~/bin/sigil-linux     # downloads this release, loads the AFI, boots to the login prompt

The console is your terminal. The login prompt appears 5 min 48 s after the SoC starts (measured on the F2; before that the host zeroes DDR4 and loads the 8 GiB disk, about 21 s, and the first run downloads the release). The F2 runs below used the sigil_host command that sigil-linux wraps (by hand, next block); sigil-linux itself passed its tests against a simulated sigil_host. Log in as sigil / sigil (sudo) or root / sigil, then for example:

gcc hello.c && ./a.out                          # native gcc 14 / glibc 2.41
numactl --hardware                              # node 0 = DDR4 48 GiB, node 1 = HBM 16 GiB
numactl --membind=1 ~/examples/memwhere 1024    # 1 GiB placed in HBM
sudo poweroff                                   # saves your disk (~/sigil-disk.ext4) for the next sigil-linux

sigil-linux copies the disk back after poweroff; Ctrl-] leaves without saving (the window is kept as ~/sigil-disk.ext4.unclean); sudo reboot keeps the session going on the same disk. The first run after an AFI load zeroes all DDR4 once, which takes about 17 s. Rerunning the setup one-liner updates ~/sigil, sigil_host and the helpers.

By hand (sigil_host), as in docs/LINUX.md §4.2:

R=https://github.com/bubblebabyboi/sigil/releases/download/sigil-linux-f2-2026-10-22
for f in SHA256SUMS fw_jump.bin Image sigil-f2.dtb sigil-debian-13-riscv64.ext4.zst; do curl -fsSLO "$R/$f"; done
sha256sum -c --ignore-missing SHA256SUMS
zstd -d --sparse sigil-debian-13-riscv64.ext4.zst     # 8 GiB ext4 image
sudo ~/sigil/fpga/host/sigil_host --linux --fw fw_jump.bin --image Image --dtb sigil-f2.dtb \
     --load 0xC80000000=sigil-debian-13-riscv64.ext4 \
     --save 0xC80000000=sigil-disk-saved.ext4:8G \
     --console

Guides: docs/LINUX.md (build it, QEMU, F2, NUMA, vector code, the disk), docs/LINUX_PLATFORM.md (memory map and devices), docs/FPGA_F2.md (the AFI and sigil_host). Bare-metal programs still work as before: docs/PROGRAMMING.md, sudo fpga/host/sigil_host --bin prog.bin (no --ignore-mem-err needed any more).

What is in the image

Layer What
Firmware OpenSBI v1.9 generic fw_jump (cbf9f673) + a Sigil patch that writes back the L1 D$ before power-off/reboot
Kernel Linux 6.12.114 LTS, sw/linux/kernel/sigil_defconfig; user-space vector on Zve64d (VLEN 512)
Device tree sigil-f2.dtb (timebase 62.5 MHz), one source sw/linux/dts/sigil.dtsi for F2, QEMU and RTL simulation
Root file system Debian 13.7 "trixie" riscv64 from snapshot.debian.org 20261020T000000Z, 257 packages, systemd 257, ext4 (8 GiB file system in the 16 GiB pmem window)
Tools build-essential (gcc/g++ 14.2, binutils 2.44, make 4.4, glibc 2.41), gdb 16.3, git 2.47, python3 3.13, numactl/libnuma 2.0.19, vim, nano, tmux, htop, strace, man pages
~/examples hello, malloc_test, numa_hbm (libnuma, DDR4 vs. HBM timing), memwhere (NUMA node of every page), rvv_vadd (RVV intrinsics), autovec (GCC auto-vectorization for Zve64d)

Memory as Linux sees it on the F2:

NUMA node Memory Physical range Size
0 (CPU node) DDR4 0x0_8000_0000 – 0xC_7FFF_FFFF 48 GiB
— DDR4 pmem window = root disk /dev/pmem0 0xC_8000_0000 – 0x10_7FFF_FFFF 16 GiB
1 (no CPUs) HBM 0x10_8000_0000 – 0x14_7FFF_FFFF 16 GiB

Proven on F2 hardware (measured 62.5 MHz)

Debian 13 on the new AFI (f2.6xlarge, us-east-1):

Check Result
SoC release → SIGIL_LINUX_BOOT_OK → login prompt 337.7 s → 347.9 s (5 min 48 s); second boot 333.2 s → 343.2 s; no kernel oops in either
Where the time goes ≈ 129 s OpenSBI + early memory setup for 64 + 16 GiB, then systemd-analyze: 10.6 s kernel + 3 min 25.5 s userspace (dev-pmem0.device 2 min 13 s); about 5 core cycles per instruction (estimate: F2 kernel time divided by QEMU icount instruction count)
Login, uname, systemd state, root on /dev/pmem0 PASS: Linux 6.12.114 + Debian 13, isa with zve64d, systemd running with no failed units, / = /dev/pmem0 ext4 rw
numactl --hardware (node 0 DDR4, node 1 HBM) PASS: 2 nodes, node 0 48305 MB with cpu 0, node 1 16110 MB without CPUs; free -h 62 GiB
numactl --membind=1 memory lands in HBM PASS: memwhere 1024 → node 1: 1024 MiB; numa_hbm: dependent load 1791 ns DDR4 / 1878 ns HBM
gcc hello.c && ./a.out, time PASS: 22.9 s; make of the 6 examples 6 min 23 s; python3 -c 9.9 s; malloc_test OK
RVV Zve64d user program (rvv_vadd) PASS: VLEN 512; GCC auto-vectorized autovec PASS
sudo, git/gdb/strace/vim/file/man PASS
poweroff → sigil_host --save → second boot from the saved disk PASS: the file written in run 1 is there, journalctl --list-boots shows both boots
sigil-linux: boot, sudo poweroff, save to ~/sigil-disk.ext4, second boot from it not yet run on an F2 (the runs above used the sigil_host command it wraps); 35/35 tests against a simulated sigil_host

22/22 acceptance checks plus the persistence check, linux-debian-73-2026-10-22/f2-boot-fixed/ (full consoles, check summaries, instance and AFI info). F2 time for all of #73: about 3.8 instance-hours (2.97 h + 0.78 h).

The memory platform (on the platform AFI agfi-0a1fd54ef68bdc754, the same CL without the core's walker-race fix and atomic A/D update (#74); not repeated on the new AFI, f2-platform-73-2026-10-22):

Test Result
Full-range memory test, CL memory engine, two seeds DDR4 64 GiB + HBM 16 GiB: 0 mismatches, 0 error responses, 4.0 GB/s
Sparse test from the core through the L1s DDR4 1,048,576 lines + HBM 262,144 lines over the whole ranges: 0 errors
Cold 64-byte refill latency from the core DDR4 729 ns (45.6 cycles avg) / HBM 813 ns (50.8 cycles avg)
Bulk load / save through PCIe 3.6 GB/s load, 1.0 GB/s save (8 threads); 4 GiB and 8 GiB images round-trip sha256-identical
#62 sticky memory error root cause: ECC on never-written DDR4; fixed by zeroing DDR4 once per AFI load (64 GiB in 17.2 s)
#63 UART drops fixed: Linux console lines intact, 16-byte UART bursts byte-exact
Test finisher, RTC power off / fail code / reboot keeping the disk window; RTC at the host's wall clock, alarm on PLIC source 11
Firmware + all 7 SDK examples, OpenSBI to S-mode PASS without --ignore-mem-err

Before the F2 Debian boot, the same OS was brought up in QEMU shaped like the platform (23/23 acceptance checks, linux-debian-73-2026-10-22), and the all-RTL SoC model booted Linux 6.12 to SIGIL_LINUX_BOOT_OK in 261 M cycles.

FPGA build of the new AFI: Vivado 2025.2, aws-fpga v2.3.5, commit 31a1568, all timing constraints met (WNS +0.095 ns on the core clock at 16 ns; HBM AXI +0.198 ns at 4 ns); 131,259 LUTs (10.08 % of the VU47P) for the full CL, 82,201 for the SoC + OCL block (f2-platform-73-oopsfix-2026-10-22). The walker race and its fix: linux-oops-fix-73-2026-10-22 (13 race tests under the checkers 0/3...

Read more

OpenROAD rerun: muse_crypto nangate45 GDS (2026-10-14, #31)

Choose a tag to compare

OpenROAD place-and-route rerun of the muse_crypto_top crypto accelerator macro on nangate45, now on the current SystemVerilog sources. GDS generated / place-and-route complete for the macro — this is not a tapeout and not full-SoC closure.

Results at the 10 ns (100 MHz) constraint:

  • Setup worst slack 4.34 ns, hold worst slack 0.039 ns, setup/hold TNS 0
  • ORFS fmax estimate 176.7 MHz
  • Route DRC 0, antenna 0, liberty max-cap/max-slew/max-fanout violators 0
  • 63,474 stdcells, die 308,436 um2, utilization 0.321, total power 0.0211 W

First rerun found 3 liberty max-capacitance violators (AOI221_X1/OAI221_X1); both cell types are now in DONT_USE_CELLS and the released rerun is liberty-clean. Full metrics and the b3 (2026-10-13) comparison: docs/evidence/openroad-nangate45-31-2026-10-14.log.

This milestone also closes the run that started with the human-readability refactor (#27), expanded CI (#28), FP vector Zve32f/Zve64f/Zve64d (#29), and the QEMU reference-boot oracle (#30).

Asset: muse_crypto_top_nangate45_6_final.gds (60 MB, 6_final.gds from the ORFS run; GDS is a release asset, not in git).

B3: muse_crypto nangate45 GDS (2026-10-13)

Choose a tag to compare

OpenROAD closure for the muse_crypto macro on nangate45 at 100 MHz (#3).

  • Detail-route DRC 0, antenna 0, liberty max-cap/slew/fanout violations 0
  • Setup worst slack +4.52 ns, hold +0.039 ns @ 10 ns, TNS 0/0
  • 61,590 stdcells, 95,431 um2 stdcell area (296,867 um2 core), 20.16 mW
  • Evidence: docs/evidence/b3-openroad-nangate45-2026-10-13.log at this tag; reproduce with make openroad then ./scripts/orfs_liberty_check.sh
  • 6_final.gds md5 6e2b5ad1ca4a7693091de3e27f5969d8

Local Docker ORFS run (emulated amd64) - an engineering closure result, not a foundry signoff.