cd /news/ai-chips/tiny-vedas-a-generic-accelerator-int… · home topics ai-chips article
[ARTICLE · art-133955] src=github.com ↗ pub= topic=ai-chips verified=true sentiment=· neutral

Tiny-Vedas: a generic accelerator interface for RISC-V, from PyTorch op to GDS

Tiny Vedas released an open-source RISC-V AI accelerator stack whose shipping RTL is a 4-stage pipelined RV32IM processor in SystemVerilog paired with an 8×8 int8 GEMM MMIO accelerator sharing DCCM over AXI4, with PyVedas compiling torch.compile output to C and then to RV32 ELF for on-core inference kernels. The repo also ships a Python instruction-set simulator for RTL trace comparison, YAML-driven decode tables, and an optional sv2v plus OpenROAD ASIC flow for core_gemm_top, while presets for VLIW, superscalar, and out-of-order variants are scaffolded but only rv32im_scalar matches implemented RTL today. The project is used as a reference for a free course on RISC-V Processor Design.

read18 min views1 publishedSep 18, 2026
Tiny-Vedas: a generic accelerator interface for RISC-V, from PyTorch op to GDS
Image: Michielbdejong (auto-discovered)

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_top and 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_hold for the duration of one START job (software does not poll DONE).

  • Decode : Spec-driven via theopen-decode-tables submodule (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.

  1. Go to riscv-gnu-toolchain releases .
  2. Download the riscv64-elf-ubuntu-<version>-gcc.tar.xz archive matching your Ubuntu version.
  3. 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
  1. 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.sv
  • rtl/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.sv
  • sw/include/soc_defines.h — C / preprocessed.S macros (MMIO_UART_ADDR ,EOT_MAGIC , …)
  • sw/include/soc_defines.inc — gas.include for.s tests

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.int32 tensors (bare-metal target has no soft-float).
  • Every graph op must have a 1:1 entry inpyvedas/runtime/ops.yaml with 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

  1. JIT (pyvedas/jit ) exports the graph and writeswork/pyvedas.my_add/generated.c ,graph.txt , andmanifest.json .
  2. The RISC-V linker builds test.elf fromgenerated.c , runtime sources from the manifest, andeot_sequence.s .
  3. 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:

  1. Checkout with submodules
  2. make deps — system packages, Python venv, RISC-V toolchain, Verilator,scripts/env.sh
  3. make decodes — regenerate the instruction decoder
  4. make soc — regenerate the MMIO map andsoc_defines.h
  5. make 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

── more in #ai-chips 4 stories · sorted by recency
── more on @tiny vedas 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/tiny-vedas-a-generic…] indexed:0 read:18min 2026-09-18 ·