An open instruction set
An ISA defines the contract between software and the CPU. RISC-V is openly specified, enabling broad adoption without proprietary ISA licensing.
RISC-V is an open instruction set architecture (ISA) that scales from tiny MCUs to Linux-capable processors. Its modular design lets hardware vendors add standardized extensions, including the RISC-V Vector Extension (RVV) for portable SIMD-style acceleration.
An ISA defines the contract between software and the CPU. RISC-V is openly specified, enabling broad adoption without proprietary ISA licensing.
RISC-V spans embedded microcontrollers, application processors, and accelerators. The same fundamentals apply across the range, with extensions to match the target.
GCC/LLVM toolchains, debuggers, and operating systems support RISC-V, making it practical for teaching, research, and product development.
The base ISA defines registers, integer arithmetic, loads/stores, branches, and calling conventions. RV32 targets 32-bit environments; RV64 supports 64-bit addressing and wider operations.
Modern systems rely on privilege levels for isolation and OS support. Typically you’ll encounter: Machine (M) for low-level control, Supervisor (S) for OS kernels, and User (U) for applications.
rv64imafdc means 64-bit base + a set of extensions.
Many Linux-class cores are commonly summarized as rv64gc (where g is a shorthand bundle).
| Extension | What it adds | Typical impact |
|---|---|---|
| I (Base) | Integer ISA (required foundation) | Baseline software compatibility |
| M | Integer multiply/divide | Better performance for arithmetic-heavy code |
| A | Atomics | Lock-free primitives, OS & multithreading support |
| F/D | Single/double-precision floating point | Scientific, DSP, graphics workloads |
| C | Compressed 16-bit instruction encodings | Smaller binaries, improved I-cache efficiency |
| V | Vector Extension (RVV) | Portable vectorization across varying hardware widths |
RVV is designed so that the same program can run efficiently on implementations with different physical vector register widths. Instead of hard-coding “128-bit” or “256-bit” vectors, code adapts to the available vector length at runtime.
RVV supports vector masks for predication and offers flexible element widths (8/16/32/64-bit, etc.). “LMUL” lets code group registers to act like wider vectors when beneficial.
A typical RVV loop chooses a vector length for the remaining elements (via vsetvl),
then performs vector operations on that chunk. This avoids a scalar “tail loop” in many cases.
while (n > 0) {
vl = vsetvl(n); // pick a VL supported by the hardware (<= n)
v = load(vptr, vl); // load vl elements
v = f(v); // compute (add/mul/exp/etc.)
store(out, v, vl); // store vl elements
vptr += vl; out += vl;
n -= vl;
}
Compilers can emit this pattern automatically when targeting RVV, or you can use RVV intrinsics for explicit control in performance-critical code.
Image/audio processing, cryptography, ML kernels, compression, and data-parallel loops where throughput matters.
Programs are less tied to a single vector width, which can improve portability across vendors and generations.
Ensure your toolchain flags, libraries, and runtime environment are built for the target ISA + V.
For portable binaries, target the minimum ISA you need. For optimized builds, compile for the exact CPU feature set (including RVV) and validate on real hardware.
# Illustrative intent (flags vary by toolchain/vendor): # - target ISA: rv64 + gc + v (vectors) # - enable vectorization (where supported) cc -O3 -march=rv64gcv -mabi=lp64d your_code.c
The safest approach is to keep a “baseline” build for compatibility and an “optimized” build for specific boards/SoCs.
lp64/lp64d for RV64).