CH32V307
CH32V307 is a higher-end WCH RISC-V microcontroller — a QingKe V4F core (RISC-V RV32IMAFC: RV32I with the M multiply/divide, A atomic, F single-precision floating-point and C compressed extensions, up to 144 MHz, with 256 KB flash and 64 KB SRAM) — the bigger sibling of the CH32V003, emulated from scratch in the browser on a from-scratch RISC-V core with a hardware FPU. It runs REAL compiled firmware: a flat flash image that boots from address 0x00000000 exactly as on silicon (the QingKe core executes the vector table's opening j handle_reset), then drives the real CH32V307 registers. The on-board peripherals shown are the user LEDs on PA0/PA1, a user button on PB4 and a USART1 serial console — with nothing invented: no breadboard, no fake audio (a bare CH32V307 dev board has no speaker on this surface, so it is honestly silent). Because the whole chip is ordinary JavaScript, it plugs into this site's shared debugger: the real RISC-V disassembler, live x0-x31, the machine CSRs and the f0-f31 float registers, side-effect-free FLASH / SRAM / peripheral memory at the real addresses, single-instruction step, execution breakpoints and write-watchpoints.
Runs on: Web browser
CH32V307 Online Emulator
Play CH32V307 using JavaScript directly in your browser.
Controls
Configurations
| Configuration | Emulator | Machine | OS | Legal | |
|---|---|---|---|---|---|
| Blink PA0/PA1 (user LEDs) | CH32V307 | CH32V307 | open | Open ⛶ | |
| Button + LED | CH32V307 | CH32V307 | open | Open ⛶ | |
| USART Hello | CH32V307 | CH32V307 | open | Open ⛶ | |
| SysTick + FPU | CH32V307 | CH32V307 | open | Open ⛶ |
Chips
Notes
Embedding
This is a two-layer stack: a real RISC-V CPU core underneath, and a from-scratch CH32V307 SoC + dev board on top. It loads real RV32IMAFC flash images and runs them on the actual on-chip peripherals — RCC clock gating, the STM32F1-style GPIO ports, USART1 and the SysTick timer — at their real addresses. The firmware is genuine compiled machine code, not a shim.
- The CPU.
rv32.jsis a from-scratch RISC-V interpreter that executes RV32IMAFC: the full RV32I integer base (all 32 registersx0..x31) plus the M multiply/divide, the A atomics, the F single-precision floating-point unit (a realf0..f31register file, computed in IEEE-754 single precision), and the C 16-bit compressed encodings. This is the Qingke V4F — the bigger sibling of the CH32V003's RV32EC core, with a hardware multiplier and an FPU. - Real reset. The QingKe core boots executing from flash address
0x00000000(which aliases the0x08000000flash), where the vector table's first entry isj handle_reset— the very first instruction fetched is the jump to the reset code, exactly like the silicon. The startup enables the FPU by settingmstatus.FS. - The board, in JavaScript.
ch32v307-board.jsmaps FLASH/SRAM/peripherals at their real CH32V307 addresses, answers the RCC clock-ready bits the firmware spins on, folds GPIOBSHR/BCRintoOUTDR, presents the user button onGPIOB->INDRbit 4, captures every byte written toUSART1->DATARinto the serial console, and runs the SysTick counter.
Debugger integration
ch32v307-debug.js reads window.EMU_BOOT and hands the shared debugger a genuine RISC-V RV32IMAFC machine — the same core the firmware runs on, exposed instruction-accurately.
- Registers.
registers()reads the full integer filex0-x31(ABI names),pc, the machine CSRsmstatus/mtvec/mepc/mcause/fcsr, and the 32 single-precision float registersf0-f31(raw bits) live each refresh; the general registers and pc are writable (x0 stays hard-wired to zero). - Disassembly. FLASH is decoded with the shared
riscvdecoder (RV32I + M + A + C). The single-precision F instructions in the SysTick+FPU program fall back to raw.word/.2byte(the shared decoder does not disassemble the F opcodes) but still execute correctly, and thef0-f31registers update live. - Single-step. Step calls
transport.stepInsn, which advances the core exactly one RISC-V instruction (16- or 32-bit); pc and the registers (integer AND float) update after each step. - Breakpoints & watchpoints. Execution breakpoints are a pc set the run-loop checks before each instruction; write watchpoints wrap the board's memory-write path (e.g.
GPIOA->OUTDRat0x4001080CorUSART1->DATARat0x40013804). Both are real. - Input. The on-board user button (PB4) is a Controls-panel button (and the physical B key) that drives
GPIOB->INDRbit 4. - Memory map. Three chips read the real address space side-effect-free: FLASH (program, disassembled, 0x00000000), SRAM (0x20000000), and the peripheral block (0x40000000 — RCC, GPIOA/B/C, USART1).
Architecture
The WCH CH32V307 is a higher-end RISC-V microcontroller: a QingKe V4F core (RV32IMAFC — RISC-V RV32I with the M, A, F and C extensions, i.e. a hardware multiplier plus a single-precision FPU and fast interrupts, up to 144 MHz) with 256 KB flash and 64 KB SRAM. This build models the chip from scratch on a from-scratch RISC-V core — the bigger sibling of the site's CH32V003.
- QingKe V4F CPU — runs the real compiled RISC-V image. RV32I is the full 32-register base; M adds multiply/divide, A adds atomics, F adds the single-precision FPU (
f0..f31), and C adds the compressed encodings. FLASH is at0x00000000(aliasing0x08000000), SRAM at0x20000000, peripherals at0x40000000. On reset the core executes from flash address 0, whose first vector-table entry isj handle_reset. - RCC (Reset & Clock Control,
0x40021000) — the firmware gates each peripheral's clock throughAPB2PCENRand spins on the clock-ready bits (HSIRDY, andHSERDY/PLLRDY); the board answers those bits so real clock-setup code proceeds. - GPIO ports A/B/C (STM32F1-style block:
CFGLR/CFGHR,INDR/OUTDR, atomicBSHR/BCR) — the on-board user LEDs are PA0/PA1 (active-high) and the user button is PB4 (reads 1 inGPIOB->INDRwhile held). - USART1 (
0x40013800) — the serial port.STATRkeepsTXE/TCasserted so polling transmit code runs, and every byte written toDATARis captured onto the on-screen serial console (TX on PA9). - SysTick / STK (
0xE000F000) — the V4 system timer (a 64-bit up-counter; this build uses the low 32-bitCNTL/CMPLR) with an enable bit and a compare flag, advanced by executed instructions; the SysTick + FPU program times its steps off it. - Content. Four original CC0 bare-metal C programs: Blink, Button + LED and USART Hello (clang
rv32imac), and SysTick + FPU (clangrv32imafc, real single-precision F instructions). No proprietary firmware is used. - Honest limits. A bare CH32V307 dev board has no on-board audio on this LED/button surface, so this emulator is genuinely silent with no sound path. The F unit is computed in double then rounded to single (a faithful approximation, not bit-exact fused rounding), and rounding-mode/exception flags are not fully modelled. USB/Ethernet, SPI/I2C, DMA, the other timers/USARTs and the interrupt-driven paths are not modelled — the bundled firmware polls RCC, GPIO, USART1 and SysTick.