logoalt Hacker News

Show HN: Fursoy – Out-of-order RV64IMAFDV core in SystemVerilog (Linux 6.6)

48 points • by fursoy • today at 2:06 PM • 16 comments • view on HN

Comments

Findecanor • today at 4:51 PM

Do post it on Reddit in https://www.reddit.com/r/RISCV/

I have seen more excitement and community around these kinds of projects there than here.

phendrenad2 • today at 5:08 PM

Doing OOO in a one-person project is impressive.

➕ show 1 reply
fursoy • today at 2:06 PM

I built Fursoy Slice-1, a 64-bit out-of-order superscalar RISC-V core (RV64IMAFDV + Zba/Zbb/Zicsr/Zifencei) in SystemVerilog, along with a minimal SoC (5-master crossbar, CLINT, PLIC, 16550 UART, and custom SBI v2.0 firmware).

At a high level, the core is 2-wide fetch/decode/rename/retire with a 128-entry ROB, 160-entry integer PRF, 8 branch checkpoints for single-cycle speculative RAT rollback, and separate Int/Mem/FP/Vec issue queues. On the memory side, it has a dual-port Sv39 DTLB (64-entry 4-way Tree-PLRU + 8-entry 2 MiB/1 GiB superpage CAM), ITLB, and a 16 KiB 8-bank non-blocking L1D. Instead of flushing dirty lines on every page-table walk, the hardware PTW snoops dirty L1D sets non-destructively so Linux page-table updates are visible directly, paired with store-queue drain on SFENCE.VMA.

In Verilator, it boots mainline Linux 6.6.50 and BusyBox userspace in ~89.8M cycles (~76.2M retired instructions, 2,255 page faults handled) while checking an 8-bucket single-owner CPI conservation invariant every cycle with 0 cycle leakage. Synthesizing the 8 main core logic blocks standalone with sv2v + Yosys + OpenSTA on Nangate 45nm (SRAMs/PRFs black-boxed, pre-P&R) meets 500 MHz across all 8/8 blocks at ~219 kGE, after rebuilding the ALU and branch unit as Kogge-Stone prefix trees and balancing high-fanout CSR/TLB paths.

I used an AI-agent-assisted workflow for RTL iteration and verification scaffolding while driving the microarchitecture, timing closure, and debugging myself. The nastiest late bug was a Linux boot livelock around ~90M cycles: per RISC-V Priv Spec §3.1.9, CSR read-modify-write instructions on `mip` have to operate on the software-writable `mip_q[9]` bit rather than the live `irq_seip_i` wire—our CSR block was feeding `mip_val` back into RMW, so whenever SBI cleared `STIP` while a PLIC IRQ was high, it permanently latched `SEIP` and trapped the kernel in `plic_handle_irq`.

For folks who have built Sv39 cores or open-source ASIC flows: do you prefer letting the PTW snoop dirty L1D lines directly like this, or forcing a clean/drain path? Also curious what people would tackle next on a single-core tree like this—an inclusive L2 cache or jumping straight to dual-core coherency.

iberator • today at 3:51 PM

Nice try but Verilog is not real hardware. I hate projects like that - you didn't produce new cpu- you just emulate it.

Build it and then I would be fan number 1!

➕ show 3 replies