SearchA-ZC › CH32V307

CH32V307

2021 Open source · CC0 On-board only Online

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.

CH32V307 at WCH ↗

Runs on: Web browser

CH32V307 Online Emulator

Play CH32V307 using JavaScript directly in your browser.

Configurations

ConfigurationEmulatorMachineOSLegal
Blink PA0/PA1 (user LEDs)CH32V307CH32V307openOpen ⛶
Button + LEDCH32V307CH32V307openOpen ⛶
USART HelloCH32V307CH32V307openOpen ⛶
SysTick + FPUCH32V307CH32V307openOpen ⛶

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.js is a from-scratch RISC-V interpreter that executes RV32IMAFC: the full RV32I integer base (all 32 registers x0..x31) plus the M multiply/divide, the A atomics, the F single-precision floating-point unit (a real f0..f31 register 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 the 0x08000000 flash), where the vector table's first entry is j handle_reset — the very first instruction fetched is the jump to the reset code, exactly like the silicon. The startup enables the FPU by setting mstatus.FS.
  • The board, in JavaScript. ch32v307-board.js maps FLASH/SRAM/peripherals at their real CH32V307 addresses, answers the RCC clock-ready bits the firmware spins on, folds GPIO BSHR/BCR into OUTDR, presents the user button on GPIOB->INDR bit 4, captures every byte written to USART1->DATAR into 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 file x0-x31 (ABI names), pc, the machine CSRs mstatus/mtvec/mepc/mcause/fcsr, and the 32 single-precision float registers f0-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 riscv decoder (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 the f0-f31 registers 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->OUTDR at 0x4001080C or USART1->DATAR at 0x40013804). Both are real.
  • Input. The on-board user button (PB4) is a Controls-panel button (and the physical B key) that drives GPIOB->INDR bit 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 at 0x00000000 (aliasing 0x08000000), SRAM at 0x20000000, peripherals at 0x40000000. On reset the core executes from flash address 0, whose first vector-table entry is j handle_reset.
  • RCC (Reset & Clock Control, 0x40021000) — the firmware gates each peripheral's clock through APB2PCENR and spins on the clock-ready bits (HSIRDY, and HSERDY/PLLRDY); the board answers those bits so real clock-setup code proceeds.
  • GPIO ports A/B/C (STM32F1-style block: CFGLR/CFGHR, INDR/OUTDR, atomic BSHR/BCR) — the on-board user LEDs are PA0/PA1 (active-high) and the user button is PB4 (reads 1 in GPIOB->INDR while held).
  • USART1 (0x40013800) — the serial port. STATR keeps TXE/TC asserted so polling transmit code runs, and every byte written to DATAR is 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-bit CNTL/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 (clang rv32imafc, 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.