A hardware WebAssembly processor implemented in Veryl. The goal is a chip (FPGA or ASIC) that natively executes WASM bytecode -- no software runtime, no JIT, just silicon running WASM instructions directly.
Early development. The ALU, operand stack, instruction decoder, fetch unit, branch table, and structured control flow are implemented and tested.
╔═══════════════════════════════════════════════════════════════════╗
║ WASM IC Core ║
║ ║
║ ┌──────────────────────────────┐ ║
║ ┌───────────┐ │ Decode │ ║
║ │ Program │ │ ┌─────────┐ ┌───────────┐ │ ║
║ │ Memory │ [8] │ │ opcode │ │ control │ │ ║
║ │ (ROM) ├──────>│ │ byte ├─>│ signals ├──┼──┐ ║
║ └─────┬─────┘ │ └─────────┘ │ (14 out) │ │ │ ║
║ ^ │ └───────────┘ │ │ ║
║ [32]│addr └──────────────────────────────┘ │ ║
║ │ │ ║
║ ┌─────┴─────┐ [32] ┌─────────────┐ [32] ┌────┴────┐ ║
║ │ ├────────>│ Branch ├────────> │ │ ║
║ │ Fetch │ instr │ Table │ target │ Operand │ ║
║ │ │ pc │ (RAM) │ pc │ Stack │ ║
║ │ 7-state │<────────┤ │ │ TOS/NOS │ ║
║ │ FSM │ [32] └──────┬──────┘ [32] │ cache │ ║
║ │ │ target ^ │ ┌─────>│ │ ║
║ └───────────┘ pc │ │ loader │result└────┬────┘ ║
║ │ │ writes │ │ ║
║ ╔════════════════════╧══╧═══╗ ┌────┴────┐ [32]│TOS ║
║ ║ Off-chip Loader ║ │ ALU │ [32]│NOS ║
║ ║ (validates, fills ║ │ (comb.) │<─────┘ ║
║ ║ branch table + memory) ║ │ 29 ops │ ║
║ ╚═══════════════════════════╝ └─────────┘ ║
║ ║
║ - - - - - - - - - - - TODO - - - - - - - - - - - - - - ║
║ ┊ Call Stack ┊ ┊ Linear Memory ┊ ┊ Top-level Core ┊ ║
║ ┊ (frames, ┊ ┊ (load/store) ┊ ┊ (wires it all ┊ ║
║ ┊ locals) ┊ ┊ ┊ ┊ together) ┊ ║
║ ┊ · · · · · ·┊ ┊· · · · · · · ·┊ ┊· · · · · · · · ┊ ║
║ ║
╚═══════════════════════════════════════════════════════════════════╝
── solid border = implemented ┊ dotted border = planned
| Module | File | Status | Docs | Description |
|---|---|---|---|---|
WasmAluPkg |
src/wasm_alu_pkg.veryl |
Done | ALU | ALU opcode enum (29 operations) |
WasmAlu |
src/wasm_alu.veryl |
Done | ALU | Combinational ALU, all i32 operations |
WasmStack |
src/wasm_stack.veryl |
Done | Stack | Operand stack with TOS/NOS caching |
WasmDecode |
src/wasm_decode.veryl |
Done | Decoder | Opcode byte to control signals (49 opcodes) |
WasmFetch |
src/wasm_fetch.veryl |
Done | Fetch | PC, bytecode fetch, LEB128, control flow |
WasmBranchTable |
src/wasm_branch_table.veryl |
Done | Branch Table | Precomputed branch target RAM |
WasmMemory |
src/wasm_memory.veryl |
Done | Memory | Byte-addressable linear memory for load/store |
| Call Stack | - | TODO | - | Function frames, locals, return addrs |
| Function Table | - | TODO | - | Indirect call support |
| Top-level Core | - | TODO | - | Wires everything together |
See the Roadmap for what's planned next.
src/
wasm_alu_pkg.veryl -- AluOp enum (Add, Sub, Mul, DivS, ...)
wasm_alu.veryl -- Combinational ALU + tests
wasm_stack.veryl -- Operand stack + tests
wasm_decode.veryl -- Instruction decoder + tests
wasm_fetch.veryl -- Fetch unit (PC, LEB128, control flow) + tests
wasm_branch_table.veryl -- Branch target RAM + tests
wasm_memory.veryl -- Linear memory (byte-addressable RAM) + tests
hello.veryl -- Placeholder
docs/ -- Detailed module documentation
target/ -- Generated SystemVerilog (git-ignored)
dependencies/ -- Veryl stdlib (git-ignored)
Veryl.toml -- Project config
# Compile Veryl -> SystemVerilog
veryl build
# Run all tests (uses Verilator)
veryl test --sim verilator
# Generated SystemVerilog ends up in target/
ls target/*.svDetailed docs for each module live in docs/:
- ALU -- i32 arithmetic, bitwise, comparison, and unary operations
- Operand Stack -- LIFO with TOS/NOS register caching
- Decoder -- opcode to control signal translation
- Fetch Unit -- PC management, LEB128 decoding, control flow, memory ops
- Branch Table -- precomputed branch target lookup
- Linear Memory -- byte-addressable RAM for load/store
- Roadmap -- what's next and stretch goals