Tiny Vedas is an open-source stack for designing, verifying, and bringing up RISC-V AI accelerators — from synthesizable processor RTL and spec-driven decode, through ISS/RTL co-simulation, to a PyTorch JIT that targets bare-metal firmware on the core.
Today, the repo ships a complete RV32IM reference core: a 4-stage in-order pipeline with Harvard memory, hazard handling, and end-to-end test infrastructure. Next, the same contracts extend to additional microarchitectures (VLIW, superscalar, out-of-order) and vector units — hardware presets and software hooks are already scaffolded in hw/ so RTL, simulation, and PyVedas can evolve together without breaking the workflow.
It is also used as a reference for the free course on RISC-V Processor Design.
| Layer | Role |
|---|---|
| RTL | Synthesizable RISC-V cores, GEMM accelerator, and SoC integration ( rtl/ ) |
| Verification | Python ISS + RTL trace comparison ( tools/rv_iss.py ,sim_manager.py ); GEMM directed/random co-sim (tools/gemm_cosim.py ) |
| Decode | YAML-driven instruction tables → SystemVerilog ( open-decode-tables/ ) |
| Primitives | Reusable arithmetic and register blocks ( SVLib/ ) |
| Software | Bare-metal runtime, printf, assembly/C/PyTorch tests |
| PyVedas | torch.compile → C → RV32 ELF for on-core inference kernels |
| PD | Optional ASIC flow: sv2v + OpenROAD ( pd/ ) —core_gemm_top (CPU + GEMM) |
The shipping RTL is a 4-stage pipelined RV32IM processor written in SystemVerilog, plus an 8×8 int8 GEMM MMIO accelerator that shares DCCM over AXI4. The CPU flavor (hw/presets/rv32im_scalar.yaml) is the baseline used by CI, examples, and the course.
Tiny Vedas is built to support multiple CPU organizations behind one hardware-config contract. Presets in hw/presets/ already describe scalar, VLIW, superscalar, and out-of-order variants with optional vector units; only rv32im_scalar matches implemented RTL today. As new microarchitectures land, sim_manager, PyVedas, and the test suite will target them through the same --hw-config YAML — so accelerator exploration stays one toolchain, not a fork per design.
-
ISA : RISC-V RV32IM (32-bit integer + multiply/divide)
-
Pipeline : 4-stage (IFU → IDU0 → IDU1 → EXU)
-
Memory : Harvard architecture — separate ICCM and DCCM (true dual-port, both ports RW). The core keeps custom fetch/LSU ports;
soc_topand the FPGA SoC convert those toAXI4 (32-bit, ID width 4, two DCCM masters) into on-chip CCM slaves. FPGA muxes DCCM port B between the core and the host (halt-and-load). ASIC PD synthesizescore_gemm_top(CPU + GEMM; memories stay off-chip IOs). -
GEMM : Output-stationary 8×8 PE array (
int8 × int8 → int32, K-tile 32) atMMIO_GEMM_ADDR(0x00300000). Packed AXI4 INCR DMA loads A/B from DCCM and writes C; the core is held viaaccel_holdfor the duration of one START job (software does not poll DONE). -
Decode : Spec-driven via the
open-decode-tablessubmodule (YAML → SystemVerilog) -
Verification : Python instruction-set simulator (ISS) compared against RTL traces
-
Arithmetic : ADD, SUB, ADDI, LUI, AUIPC
-
Logical : AND, OR, XOR, ANDI, ORI, XORI
-
Shifts : SLL, SRL, SRA, SLLI, SRLI, SRAI
-
Comparison : SLT, SLTU, SLTI, SLTIU
-
Branches : BEQ, BNE, BLT, BGE, BLTU, BGEU
-
Jumps : JAL, JALR
-
Memory : LB, LH, LW, LBU, LHU, SB, SH, SW
-
Multiply/Divide : MUL, MULH, MULHU, MULHSU, DIV, DIVU, REM, REMU
-
System : NOP (
addi x0, x0, 0), ECALL (decoded; no trap handler yet — behaves as NOP) -
Register forwarding from EXU to IDU1
-
Pipeline flush on taken branches and jumps
-
Register scoreboard for RAW hazard detection
-
Multi-cycle multiplier and divider
-
Booth-encoded 32×32 multiplier with per-operand signedness (MUL / MULH / MULHU / MULHSU)
-
Non-restoring divider with combinational Kogge-Stone adders on the iteration path
-
Unaligned load/store support with byte-strobe DCCM writes (no store RMW) and strobe-aware store-to-load forwarding. Dual RW DCCM ports complete both beats of an unaligned access in one cycle (stall only on a same-cycle load/store port conflict).
One START programs a single 2-D DCCM matrix multiply C = A × B:
| Item | Value |
|---|---|
| Array | 8×8 output-stationary PEs |
| Datatypes | int8 × int8 → int32 accumulators |
| K tiling | 32-element tiles, dual ping-pong A/B buffers |
| DMA | 32-bit AXI4 INCR bursts (A along K, B along N, C int32 along N) |
| Wait | Core accel_hold for the job; tests must not poll STATUS before reading C |
CSRs (rtl/include/gemm_csrs.svh): BASE_A/B/C, M, N, K, CTRL (START / soft reset), STATUS (BUSY / DONE). DONE is sticky until the next START. Firmware examples: tests/asm/gemm_8x8.s, tests/c/gemm_8x8.c, tests/c/gemm_multi.c.
Tiny-Vedas/
├── rtl/ # Processor + accelerator RTL
│ ├── core_top.sv # CPU pipeline (memory ports exposed)
│ ├── soc_top.sv # core_top + GEMM + AXI4 adapters + ICCM/DCCM
│ ├── core_top.flist # Sim file list (core + SoC + bus + GEMM)
│ ├── accel/ # GEMM MMIO engine (CSR, DMA, 8×8 PE array)
│ │ ├── gemm_top.sv # Job FSM + ping-pong tile orchestration
│ │ ├── gemm_csr.sv # AXI-Lite CSRs at 0x00300000
│ │ ├── gemm_dma.sv # Packed AXI4 INCR bursts to DCCM
│ │ ├── gemm_datapath.sv # Systolic array + accumulators
│ │ └── gemm_pe.sv # int8 MAC PE
│ ├── bus/ # AXI4 fetch/LSU masters, CCM slaves, master mux
│ ├── ifu/ # Instruction fetch unit
│ ├── idu/ # Decode stages, regfile, scoreboard
│ │ ├── rv32im_decoder.sv # Generated — do not hand-edit
│ │ └── decode_out_t.svh # Generated — do not hand-edit
│ ├── exu/ # ALU, MUL, DIV, LSU
│ ├── include/ # global.svh, types.svh, axi4.svh, gemm_csrs.svh, mmio_map.svh
│ └── lib/ # Byte-write ICCM/DCCM (`sync_tdp_mem`)
├── fpga/alveo_u280/ # Alveo U280 bitstream, host load, card smoke
├── pd/ # ASIC PD: sv2v + OpenROAD (`core_gemm_top`)
│ ├── rtl/core_gemm_top.sv # PD wrapper: core_top + gemm_top
│ ├── platforms/ # ASAP7 / sky130 YAML
│ └── README.md
├── dv/
│ ├── sv/ # core_top_tb.sv, gemm_top_tb.sv, lsu_tb.sv
│ └── verilator/ # Verilator C++ harness
├── hw/ # Hardware presets (scalar, VLIW, OoO + vector)
│ ├── presets/ # YAML configs shared by RTL/SW (see hw/README.md)
│ ├── soc/ # SoC device map (UART, GEMM, EOT)
│ └── types.py # Typed HwConfig
├── tests/
│ ├── asm/ # Assembly test programs (incl. gemm_8x8)
│ ├── c/ # C tests (helloworld, iaxpy, gemm_8x8, gemm_multi)
│ ├── elf/ # Prebuilt ELF binaries (dhrystone)
│ ├── pyvedas/ # PyTorch → JIT model specs (incl. gemm_mmio)
│ ├── smoke.tlist # Regression test list
│ └── gemm.tlist # GEMM-only regression
├── pyvedas/ # PyTorch → Tiny-Vedas JIT
├── tools/
│ ├── sim_manager.py # Main test runner (compile → ISS → RTL → compare)
│ ├── rv_iss.py # Reference instruction-set simulator
│ └── gemm_cosim.py # Directed / random GEMM co-simulation
├── sw/
│ ├── include/ # soc_defines.h (generated — do not hand-edit)
│ └── vedas_printf/ # Bare-metal printf library for C tests
├── SVLib/ # Git submodule — reusable SystemVerilog primitives
├── open-decode-tables/ # Git submodule — YAML decode table generator
├── scripts/
│ ├── install_deps.sh # Dependency installer (`make deps`)
│ ├── env.sh # Generated PATH + venv (by `make deps`)
│ ├── with_env.sh # Wrapper used by Makefile targets
│ └── pd_docker.sh # OpenROAD Docker wrapper for rtl2gds
├── .github/workflows/ci.yml # GitHub Actions CI pipeline
├── Makefile
├── requirements.txt
└── LICENSE
| Tool | Purpose |
|---|---|
| Verilator | RTL simulation (primary; used in CI) |
| riscv64-unknown-elf-gcc | Bare-metal cross-compiler for test programs (RV32IM / ILP32) |
| Python 3 | sim_manager.py ,rv_iss.py , decode generation |
| Xilinx Vivado (optional) | XSim simulation — only needed if you prefer make smoke over Verilator |
Tested on Ubuntu 22.04 and 24.04. Other Linux distributions should work with equivalent packages installed manually.
git clone --recurse-submodules https://github.com/siliscale/Tiny-Vedas.git
cd Tiny-Vedas
If you already cloned without submodules:
git submodule update --init --recursive
On Ubuntu, make deps installs everything needed for simulation and verification:
- System build packages (
build-essential, Verilator build deps) - Python virtual environment with packages from
requirements.txt - Prebuilt RISC-V GNU bare-metal toolchain (
riscv64-unknown-elf-gcc) into.local/riscv/ - Latest stable Verilator compiled from source into
.local/verilator/
make deps
make deps also generates scripts/env.sh (PATH + venv) and verifies the toolchain. All Makefile test targets use it automatically via scripts/with_env.sh, so CI and local runs work without manual setup.
For interactive shells, source the environment once per session:
source scripts/env.sh
riscv64-unknown-elf-gcc --version
verilator --version
Override pinned versions if needed:
RISCV_TOOLCHAIN_VERSION=2026.06.05 make deps # default
VERILATOR_TAG=v5.048 make deps # pin a specific Verilator release
FORCE_RISCV_TOOLCHAIN_REINSTALL=1 make deps # re-download toolchain
FORCE_VERILATOR_REBUILD=1 make deps # rebuild Verilator
Do not run make deps with sudo — only the apt step needs elevated privileges. If a previous sudo make deps left deps/verilator root-owned, fix ownership then rebuild:
sudo chown -R "$USER:$USER" deps/verilator
FORCE_VERILATOR_REBUILD=1 make deps
make smoke-verilator
make smoke
./tools/sim_manager.py -s verilator -n asm.basic_alu_r
./tools/sim_manager.py -s verilator -n c.helloworld
./scripts/with_env.sh ./tools/sim_manager.py -s verilator -n pyvedas.vector_add
Tiny Vedas compiles bare-metal test programs with riscv64-unknown-elf-gcc using -march=rv32im -mabi=ilp32. Do not use the Linux cross-compiler ( riscv64-linux-gnu-gcc) or distribution packages that lack newlib — they will not produce working bare-metal ELFs.
make deps downloads a prebuilt riscv64-unknown-elf toolchain from the riscv-collab/riscv-gnu-toolchain releases page and installs it to .local/riscv/. The Ubuntu series (22.04 or 24.04) is detected automatically.
- Go to riscv-gnu-toolchain releases .
- Download the
riscv64-elf-ubuntu-<version>-gcc.tar.xzarchive matching your Ubuntu version. - Extract and add to your
PATH:
wget https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2026.06.05/riscv64-elf-ubuntu-22.04-gcc.tar.xz
mkdir -p ~/.local
tar -xJf riscv64-elf-ubuntu-22.04-gcc.tar.xz -C ~/.local
export PATH="$HOME/.local/riscv/bin:$PATH"
source ~/.bashrc
- Verify RV32IM support:
riscv64-unknown-elf-gcc --version
echo 'int main(void) { return 0; }' | riscv64-unknown-elf-gcc -march=rv32im -mabi=ilp32 -nostdlib -x c -
If prebuilt binaries are unavailable for your platform, follow the build instructions in the riscv-gnu-toolchain README. Configure for bare metal:
./configure --prefix=/opt/riscv --with-arch=rv32im --with-abi=ilp32
make -j$(nproc)
This takes a long time. Prefer the prebuilt nightly releases for development and CI.
All tests are driven by tools/sim_manager.py. Tests are named <type>.<name>:
| Prefix | Source | Example |
|---|---|---|
asm. |
tests/asm/<name>.s |
asm.basic_mul |
c. |
tests/c/<name>.c |
c.helloworld |
elf. |
tests/elf/<name> (prebuilt) |
elf.dhrystone |
pyvedas. |
tests/pyvedas/<name>.py (JIT → ELF) |
pyvedas.vector_add |
./scripts/with_env.sh ./tools/sim_manager.py -s <simulator> (-n <test> | -t <task-list>)
-s, --simulator verilator | xsim
-n, --test-name Run a single test (e.g. asm.basic_alu_r)
-t, --task-list Run all tests listed in a file (e.g. tests/smoke.tlist)
--hw-config Hardware preset YAML (default: hw/presets/rv32im_scalar.yaml)
--vcd Verilator waveform (core_top.vcd); omit for smoke/CI
make smoke-verilator and make smoke invoke with_env.sh automatically.
| Target | Command |
|---|---|
make deps |
Install system packages, Python venv, RISC-V toolchain, and Verilator |
make smoke-verilator |
Run the smoke regression via Verilator (CI default) |
make smoke |
Run the smoke regression via XSim (requires Vivado) |
make fpga alveo_u280 |
Build the Alveo U280 bitstream (Vivado 2023.2) |
make fpga_smoke alveo_u280 |
Run tests/smoke.tlist on the programmed Alveo (needs sudo) |
make gemm-directed |
Directed GEMM RTL vs golden ( tools/gemm_cosim.py ) |
make gemm-cosim |
Directed + 100 random GEMM seeds |
make rtl2gds |
ASIC PD: sv2v + OpenROAD ( core_gemm_top ; seepd/README.md ) |
make decodes |
Regenerate rtl/idu/rv32im_decoder.sv from YAML |
make soc |
Regenerate mmio_map.svh andsw/include/soc_defines.h fromhw/soc/ |
make clean |
Remove build artifacts ( work/ ,obj_dir/ , logs, VCDs) |
Each test writes artifacts to work/<test>/:
| File | Contents |
|---|---|
iss.log |
Golden ISS execution trace |
rtl.log |
RTL architectural trace |
sim.log |
Simulator stdout and comparison errors |
console.log |
Program UART output |
stats.txt |
IPC/CPI performance metrics |
core_top.vcd |
Waveform (Verilator --vcd only; off by default) |
Tiny Vedas uses co-simulation: a Python ISS generates a golden trace, the RTL simulator produces its own trace, and sim_manager.py compares them instruction by instruction (PC, opcode, register writes, memory stores, branches).
Programs signal completion by storing EOT_MAGIC (0xdeadbeef) to MMIO_EOT_ADDR (0x10000000). See tests/asm/eot_sequence.s and sw/include/soc_defines.h.
The multiply unit is a Booth-encoded 32×32 multiplier. Operands enter at EXU
stage e2; the 64-bit product is registered at e3 and written when sideband
latency (MUL_LAT) expires.
| RV32M instruction | rs1 sign | rs2 sign |
|---|---|---|
| MUL, MULH | signed | signed |
| MULHU | unsigned | unsigned |
| MULHSU | signed | unsigned |
Inside mul, the signed operand is always the multiplicand and the
unsigned operand is Booth-scanned as the multiplier. When rs1 is unsigned
and rs2 is signed, operands are swapped (product is commutative). Separate
controls drive multiplicand sign extension (mc_sign) and unsigned-multiplier
correction (mult_unsign); a single global unsigned flag is not sufficient for
MULHSU.
Pipeline placement is configured in rtl/include/mul_pd_config.svh (included by
exu_mul). At most one internal register stage should be enabled for PD
experiments — see pd/README.md.
Final CPA (CPA_ALGORITHM on SVLib mul):
| Value | Module | Notes |
|---|---|---|
0 |
adder_pipe + RCA |
PIPE_STAGES_CPA splits width |
1 |
adder_pipe + 4-bit CLA |
Default for generic builds |
2 |
kogge_stone_pipe |
2-cycle CPA, one flop mid prefix tree; productionexu_mul uses this |
| Path | When | Latency |
|---|---|---|
| Fast | Divide by zero/one, zero dividend, signed overflow, or both magnitudes ≤4 bits ( small_div ) |
1 cycle after issue |
| Slow | Everything else — 32-step non-restoring divider on absolute magnitudes | ~33 cycles |
The slow path uses combinational kogge_stone_adder instances for the
per-iteration trial add/subtract and remainder correction. Do not use
kogge_stone_pipe here — that module has a pipeline register and is reserved
for the multiplier CPA.
| Module | Registers | Use |
|---|---|---|
adder |
No | Generic wrapper: ALGORITHM 0=RCA, 1=CLA, 2=Kogge-Stone (comb.) |
kogge_stone_adder |
No | Combinational Kogge-Stone prefix adder (power-of-2 width) |
kogge_stone_pipe |
One | Pipelined Kogge-Stone (prefix tree split across two cycles) |
adder_pipe |
Optional | Multi-lane pipelined CPA for non-Kogge multiplier configs |
See SVLib/README.md for the full library inventory.
Smoke tests cover ALU, forwarding, multiply, divide (asm.basic_div,
asm.div_regression), load/store, branches, jumps, C programs, PyVedas JIT tests
(pyvedas.{vector,matrix,tensor}_{add,mul}), GEMM ( asm.gemm_8x8, c.gemm_8x8,
c.gemm_multi, pyvedas.gemm_mmio), and Dhrystone. tests/gemm.tlist runs the
GEMM subset alone.
| Memory | Depth | Width | Notes |
|---|---|---|---|
| ICCM (instructions) | 2^18 words | 32-bit | Loaded from ELF .text section |
| DCCM (data) | 2^18 words | 32-bit | Dual RW ports (byte strobes); loaded from .data ,.rodata ,.bss , etc. |
Configured in rtl/include/global.svh. The Alveo overlay uses smaller windows (32 KiB ICCM / 1 MiB DCCM, BAR2 2 MiB); see fpga/alveo_u280/README.md. UART (0x00200000), GEMM ( 0x00300000), and EOT ( 0x10000000) writes are decoded on the core store path and do not enter DCCM as MMIO. Addresses come from hw/soc/default.yaml; software uses generated sw/include/soc_defines.h.
| Address | Purpose |
|---|---|
SOC_LINK_ADDRESS (0x00100000 ) |
Default link address for test programs ( -Wl,-Ttext=0x100000 ) |
MMIO_UART_ADDR (0x00200000 ) |
MMIO UART — bare-metal printf output (sw/vedas_printf ) |
MMIO_GEMM_ADDR (0x00300000 ) |
GEMM CSRs (BASE_A/B/C, M/N/K, CTRL, STATUS) — see rtl/include/gemm_csrs.svh |
MMIO_EOT_ADDR (0x10000000 ) |
End-of-test flag — write EOT_MAGIC to halt simulation |
0x80000000 |
Default initial stack pointer (register x2) |
The reset vector is taken from the ELF _start symbol, not hardcoded.
Instruction decode logic is generated from YAML, not hand-written. The source of truth is open-decode-tables/tables/rv32im.yaml.
make decodes
This regenerates:
rtl/idu/rv32im_decoder.svrtl/idu/decode_out_t.svh
To add or modify instructions, edit the YAML in the open-decode-tables submodule, commit and push there, then update the submodule pointer in this repo and run make decodes.
MMIO devices (UART, GEMM, EOT) are described in hw/soc/default.yaml, not hardcoded in RTL or C. CPU presets select the map with soc: default.
make soc
This regenerates:
rtl/include/mmio_map.svh— address ranges and indices forrtl/bus/mmio_mux.svsw/include/soc_defines.h— C / preprocessed.Smacros (MMIO_UART_ADDR,EOT_MAGIC, …)sw/include/soc_defines.inc— gas.includefor.stests
sim_manager.py runs the same generation at the start of a test. To add a device, edit the YAML and re-run make soc. Bare-metal software includes soc_defines.h and uses the generated macros — see sw/vedas_printf/vedas_printf.c.
Create tests/asm/my_test.s:
.globl _start
.section .text
_start:
li x1, 42
add x2, x1, x1
.include "eot_sequence.s"
Run with:
./tools/sim_manager.py -s verilator -n asm.my_test
Create tests/c/my_test.c using vedas_printf for output. sim_manager.py compiles sw/vedas_printf/vedas_printf.c alongside the test with -march=rv32im -mabi=ilp32 -nostdlib -lgcc (required by the prebuilt bare-metal toolchain). The end-of-test sequence comes from tests/c/asm_functions/eot_sequence.s.
PyVedas tests are model spec files under tests/pyvedas/. Each file describes a small torch.compile module and concrete trace inputs. sim_manager.py JIT-compiles the model to C, links it with the PyVedas runtime, builds an RV32 ELF, and runs the usual ISS/RTL comparison.
Prerequisites: run make deps once — it installs CPU PyTorch into the repo venv/ (used automatically by sim_manager.py). For JIT-only debugging you can also use pyvedas/.venv; see pyvedas/README.md.
Create tests/pyvedas/my_add.py:
"""PyVedas smoke test: elementwise add."""
import torch
class MyAdd(torch.nn.Module):
def forward(self, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
return x + y
MODEL = torch.compile(MyAdd())
TRACE_INPUTS = (
torch.tensor([1, 2, 3, 4], dtype=torch.int32),
torch.tensor([10, 20, 30, 40], dtype=torch.int32),
)
| Symbol | Purpose |
|---|---|
MODEL |
torch.compile module exported by the JIT |
TRACE_INPUTS |
Tuple of concrete tensors — used for torch.export tracingand to bake static buffer values intogenerated.c |
Constraints today
- Use
torch.int32tensors (bare-metal target has no soft-float). - Every graph op must have a 1:1 entry in
pyvedas/runtime/ops.yamlwith a matching C kernel (e.g.aten.add.Tensor,aten.mul.Tensor). Adding a new op requires a registry entry and runtime implementation — seepyvedas/README.md .
Run with:
./scripts/with_env.sh ./tools/sim_manager.py -s verilator -n pyvedas.my_add
Add the test name to tests/smoke.tlist to include it in make smoke-verilator:
pyvedas.my_add
What happens under the hood
- JIT (
pyvedas/jit) exports the graph and writeswork/pyvedas.my_add/generated.c,graph.txt, andmanifest.json. - The RISC-V linker builds
test.elffromgenerated.c, runtime sources from the manifest, andeot_sequence.s. - ISS and Verilator traces are compared like any other test.
Inspect JIT output on failure: work/pyvedas.my_add/jit.log, compile.log, sim.log.
The core and GEMM are synthesizable. Simulation and FPGA SoCs sit outside
core_top: AXI4 adapters, ICCM/DCCM slaves, and gemm_top (rtl/bus/,
rtl/accel/, rtl/soc_top.sv, fpga/alveo_u280/rtl/). ASIC PD nets
core_gemm_top (CPU + GEMM, memories as IOs) — see pd/README.md.
FPGA build/program/smoke:
make fpga alveo_u280 # bitstream (Vivado 2023.2)
make fpga_smoke alveo_u280 # PCIe load + EOT on the card (sudo)
For ASIC physical design (SystemVerilog → Verilog via sv2v, then OpenROAD-flow-scripts), see pd/README.md:
make config # CPU flavor + PDK platform
make sv2v # convert RTL only
make rtl2gds # sv2v + synthesis/place/route/GDS
make rtl2gds ORFS_TARGET=synth # stop after synthesis
ORFS_TARGET=all PD_PLATFORM=ci-asap7 ./scripts/pd_docker.sh make rtl2gds
make decodes # ensure decoder is up to date before synthesis
make soc # ensure MMIO map + soc_defines.h match hw/soc/
From RTL simulation (see work/<test>/stats.txt after a run):
| Benchmark | Instructions | Cycles | IPC |
|---|---|---|---|
| c.helloworld | 760 | 2293 | 0.3314 |
| c.iaxpy | 109 | 235 | 0.4638 |
| elf.dhrystone | 640720 | 1274337 | 0.5028 |
On Alveo U280 (100 MHz core, host-timed EOT) elf.dhrystone is ~12.9 ms for 2000 runs → ~155k dps / ~88.5 DMIPS (~0.89 DMIPS/MHz). That matches the sim cycle count (1.274M cycles ≈ 12.7 ms at 100 MHz).
| Submodule | Repository | Purpose |
|---|---|---|
SVLib |
siliscale/SVLib | Registers, program counter, arithmetic primitives |
open-decode-tables |
siliscale/open-decode-tables | YAML → SystemVerilog decode generator |
After pulling submodule updates:
git submodule update --init --recursive
make decodes
make soc
GitHub Actions runs on every push and pull request to main. The workflow (.github/workflows/ci.yml) mirrors a from-scratch developer setup:
- Checkout with submodules
make deps— system packages, Python venv, RISC-V toolchain, Verilator,scripts/env.shmake decodes— regenerate the instruction decodermake soc— regenerate the MMIO map andsoc_defines.hmake smoke-verilator— full smoke regression (tests/smoke.tlist)
No Vivado license is required. make deps writes scripts/env.sh; subsequent make targets load it automatically — no manual PATH or source venv/bin/activate in CI.
If CI fails, check the job log for the failing test name, then reproduce locally with:
make deps # if not already done
./scripts/with_env.sh ./tools/sim_manager.py -s verilator -n <test.name>
This repository is developed and maintained by Siliscale. We do not accept external contributions — please do not open pull requests or submit patches.
The project is open source under the Apache License 2.0; you are free to use, study, and fork it for your own work. For collaboration, partnerships, or commercial engagement, see Business inquiries.
For partnerships, consulting, custom accelerator work, or commercial licensing questions, contact marco@siliscale.com.
Apache License 2.0 — see LICENSE.
- NOTICE — attribution for this repo and bundled submodules
- THIRD_PARTY.md — dev-only tools vs shipped components
SPDX: Apache-2.0