RISC-V bare metal compiler

Compile to bare metal.

A systems language for RISC-V embedded. No LLVM, no runtime, no external toolchain. Source code goes in, firmware comes out.

terminal

Debugger

Scrub through execution.

Every cycle recorded. Drag the timeline to see registers change and GPIO pins toggle.

time-travel debuggercycle 1 / 500
x0 0x00000000 ra 0x00000000 sp 0x3fce4000 gp 0x00000000
tp 0x00000000 t0 0x00000000 t1 0x00000000 t2 0x00000000
s0 0x00000000 s1 0x00000000 a0 0x00000000 a1 0x00000000
a2 0x00000000 a3 0x00000000 a4 0x00000000 a5 0x00000000
a6 0x00000000 a7 0x00000000 s2 0x00000000 s3 0x00000000
s4 0x00000000 s5 0x00000000 s6 0x00000000 s7 0x00000000
s8 0x00000000 s9 0x00000000 s10 0x00000000 s11 0x00000000
t3 0x00000000 t4 0x00000000 t5 0x00000000 t6 0x00000000
GPIO pins
0
1
2
3
4
5
6
7

Features

What it actually does.

No roadmap promises. This is what works right now.

No LLVM

Straight to machine code. 8 optimizer passes, RV32C compression. The whole compiler is about 10K lines of Rust.

Peripheral ownership

Claim a GPIO pin twice and the compiler yells at you. Ownership is tracked at the type level, not at runtime.

Error unions + try

Functions return values or errors. try unwraps or propagates. No exceptions, no hidden control flow.

Time-travel debugger

Every CPU cycle gets recorded. Scrub backward through execution and see exactly what wrote that register.

Built-in emulator

RV32IM emulator with MMIO logging baked in. Write code, run it, see GPIO toggles. No hardware needed to start.

Agent-friendly

JSON errors, a check command, deterministic output. Built so AI agents can compile and verify without hand-holding.

Syntax

Looks like Rust. Compiles to bare metal.

If you can read Rust, you can read Kov. Board definitions are part of the grammar.

blink.kvkov
// board definition is the language
board esp32c3 {
    gpio: GPIO @ 0x6000_4000,
    uart: UART @ 0x6000_0000,
    clock: 160_000_000,
}

fn main(b: &mut esp32c3) {
    let led = b.gpio.pin(2, .output);
    let tx = b.uart.open(115200);

    loop {
        led.high();
        delay_ms(500);
        led.low();
        delay_ms(500);
        tx.write("blink\n");
    }
}

Comparison

Honest comparison.

CRustKov
LLVM requiredYesYesNo
Peripheral safetyNoneRuntimeCompile-time
Stack overflowSilentPanicCompile error
WCET analysisExternal toolExternal toolBuilt-in
Interrupt safetyManualRTIC macroStatic analysis
Runs in browserNoNoYes (WASM)
Compile time2–10s10–60s<1ms

Built from scratch. All open source.

One person, Rust, no dependencies. Compiler, emulator, optimizer, and now a browser playground.

Follow on GitHub