|
8 | 8 | __/ | |
9 | 9 | |___/ |
10 | 10 | ``` |
| 11 | + |
| 12 | +A small, formally verified RISC-V SoC. |
| 13 | + |
| 14 | +## Features |
| 15 | + |
| 16 | +- **nyanrv** — RV32I + Zicsr soft CPU with M-mode interrupt support (MTI + MEI) |
| 17 | +- **UART TX/RX** — parameterised baud-rate UART with formal verification |
| 18 | +- **SDRAM controller** — Gowin SDRAM interface (formally verified) |
| 19 | +- Formally verified with [riscv-formal](https://github.com/YosysHQ/riscv-formal) and [SymbiYosys](https://github.com/YosysHQ/sby) |
| 20 | +- CI runs `prove` + `cover` on every push |
| 21 | + |
| 22 | +## Directory structure |
| 23 | + |
| 24 | +``` |
| 25 | +NyanSoC/ |
| 26 | +├── rtl/ |
| 27 | +│ ├── nyanrv.v # RV32I + Zicsr CPU core |
| 28 | +│ ├── uart/ |
| 29 | +│ │ ├── uart_tx.v # UART transmitter |
| 30 | +│ │ └── uart_rx.v # UART receiver |
| 31 | +│ └── gowin/ |
| 32 | +│ └── sdram_ctrl.v # SDRAM controller |
| 33 | +├── boards/ |
| 34 | +│ └── tangnano20k/ # Tang Nano 20K top-level + P&R scripts (only supported board) |
| 35 | +├── firmware/ |
| 36 | +│ ├── blinky/ # LED blink (C) |
| 37 | +│ └── hello_world/ # "Hello, World!" over UART (C) |
| 38 | +├── formal/ |
| 39 | +│ ├── nyanrv/ # riscv-formal config and wrapper for nyanrv |
| 40 | +│ └── Makefile # Formal verification flow |
| 41 | +└── sim/ |
| 42 | + └── sw/ # RV32I assembly test suite (iverilog) |
| 43 | +``` |
| 44 | + |
| 45 | +## Memory map (Tang Nano 20K SoC) |
| 46 | + |
| 47 | +| Address range | Region | |
| 48 | +|---------------------------|---------------------| |
| 49 | +| `0x0000_0000–0x0000_0FFF` | IMEM (1 KiB, LUT-ROM) | |
| 50 | +| `0x0001_0000–0x0001_0FFF` | DMEM (1 KiB, BRAM) | |
| 51 | +| `0x0002_0000` | GPIO — bits [5:0] drive LED[5:0] | |
| 52 | +| `0x0003_0004` | UART TX — write: send byte; read: `{31'b0, busy}` | |
| 53 | + |
| 54 | +> **Supported boards:** Tang Nano 20K only. |
| 55 | +
|
| 56 | +## Prerequisites |
| 57 | + |
| 58 | +| Tool | Purpose | |
| 59 | +|------|---------| |
| 60 | +| [OSS CAD Suite](https://github.com/YosysHQ/oss-cad-suite-build) | Simulation, synthesis, formal verification | |
| 61 | +| [Gowin EDA](https://www.gowinsemi.com/en/support/home/) | `gowin_pack` for Tang Nano 20K bitstream | |
| 62 | +| [openFPGALoader](https://github.com/trabucayre/openFPGALoader) | Flashing the FPGA | |
| 63 | +| `riscv64-elf-gcc` | Cross-compiler for firmware and sim tests | |
| 64 | + |
| 65 | +Source the OSS CAD Suite environment before running any make targets: |
| 66 | + |
| 67 | +```sh |
| 68 | +source /path/to/oss-cad-suite/environment |
| 69 | +``` |
| 70 | + |
| 71 | +## Quick start |
| 72 | + |
| 73 | +```sh |
| 74 | +# Run all CPU simulation tests |
| 75 | +make sim |
| 76 | + |
| 77 | +# Run all formal proofs and cover checks |
| 78 | +make prove |
| 79 | +make cover |
| 80 | + |
| 81 | +# Build firmware and synthesise bitstream for Tang Nano 20K |
| 82 | +make bitstream |
| 83 | + |
| 84 | +# Flash to SRAM (volatile, lost on power cycle) |
| 85 | +make flash-sram |
| 86 | + |
| 87 | +# Flash to SPI flash (persistent) |
| 88 | +make flash |
| 89 | +``` |
| 90 | + |
| 91 | +## Simulation tests |
| 92 | + |
| 93 | +The `sim/sw/` test suite assembles RV32I programs with `riscv64-elf-gcc` and |
| 94 | +runs them under [Icarus Verilog](http://iverilog.icarus.com/): |
| 95 | + |
| 96 | +```sh |
| 97 | +make sim # run all tests |
| 98 | +make sim-waves # run first test and dump a VCD waveform |
| 99 | +``` |
| 100 | + |
| 101 | +Individual tests: `test_alu`, `test_branch`, `test_mem`, `test_jump`, |
| 102 | +`test_csr`, `test_irq`. |
| 103 | + |
| 104 | +## Formal verification |
| 105 | + |
| 106 | +```sh |
| 107 | +make prove # BMC checks: nyanrv (riscv-formal) + UART TX/RX |
| 108 | +make cover # Cover checks: reachability for all modules |
| 109 | +``` |
| 110 | + |
| 111 | +The riscv-formal core files live in `formal/nyanrv/` and are synced into the |
| 112 | +`riscv-formal` submodule at build time via `make -C formal setup`. |
| 113 | + |
| 114 | +## UART modules |
| 115 | + |
| 116 | +Both `uart_tx` and `uart_rx` are parameterised by `CLK_FREQ` and `BAUD_RATE`: |
| 117 | + |
| 118 | +```verilog |
| 119 | +uart_rx #(.CLK_FREQ(27_000_000), .BAUD_RATE(115200)) u_rx ( ... ); |
| 120 | +uart_tx #(.CLK_FREQ(27_000_000), .BAUD_RATE(115200)) u_tx ( ... ); |
| 121 | +``` |
| 122 | + |
| 123 | +See `rtl/uart/uart_rx_example.v` for a loopback echo example, and |
| 124 | +`rtl/uart/uart_tx_example.v` for a continuous transmit example. |
0 commit comments