The other day we reported about GigaDevice GD32V general-purpose 32-bit RISC-V microcontroller, and one of the commenters asked whether it was rv32imac or rv32emac, and it turned out to be the former. In most case, silicon vendors report whether they are using 32-bit, 64-bit or the upcoming 128-bit RISC-V processors, but rarely go into details, so I asked why it mattered and got the following answer:

RISC-V is a federation of ISA extensions — from the baseline rv{32|64|128}I, to an arbitrary combination of a handful of extensions. There are combinations which are dubbed ‘application-processor level’ (the G subset), but implementations can and often are not G-compliant, which is naturally the case with MCUs. Difference between rv32i and rv32e is 32-strong vs 16-strong GPR file, respectively. In the case of GD32VF103, rv32imac stands for a ‘full-size GPR file, integer mul/div, atomics, compressed (16bit) ISA’ set. What is missing from ‘application-processor level’ (G) is the FPU – F & D extensions.

So I went to look for more details and Wikipedia has a good run-down of the RISC-V ISA bases, and extensions.

RISC-V Bases

There are currently four ISA bases:

RV32I – Base Integer Instruction Set, 32-bit. Currently version 2.1

RV32E – Base Integer Instruction Set (embedded), 32-bit, 16 registers with a smaller instruction set. Current version 1.9 but not frozen yet

RV64I – Base Integer Instruction Set, 64-bit. Currently version 2.0

RV128I – Base Integer Instruction Set, 128-bit. Currently version 1.7, but not frozen yet.

Provided Wikipedia status information is right, we are more likely to see RV32I and RV64I designs right now since RV32E and RV128I specifications are not finalized.

RISC-V Extensions

Once we have the base we can add extensions to it to define the exact features of the core (frozen extensions – as of August 2019 – highlighted in bold) :

M – Standard Extension for Integer Multiplication and Division

A – Standard Extension for Atomic Instructions

F – Standard Extension for Single-Precision Floating-Point

D – Standard Extension for Double-Precision Floating-Point

G – Shorthand for the base and above extensions

Q – Standard Extension for Quad-Precision Floating-Point

L – Standard Extension for Decimal Floating-Point

C – Standard Extension for Compressed Instructions

B – Standard Extension for Bit Manipulation

J – Standard Extension for Dynamically Translated Languages such as C#, Go, Haskell, Java, JavaScript, OCaml, PHP, Python, R, Ruby, Scala or WebAssembly

T – Standard Extension for Transactional Memory

P – Standard Extension for Packed-SIMD Instructions

V – Standard Extension for Vector Operations

N – Standard Extension for User-Level Interrupts

H – Standard Extension for Hypervisor

The first remark is that many extensions are still being finalized, and if I understand correctly support for features such as user-level interrupts, SIMD instructions and hypervisor support are still being worked on.

RISC-V “Codes” Examples

We’ve learned that GD32V features an RV32IMAC core. Let’s decode what that means: GD32V is a 32-bit RISC-V core (RV32I) with integer multiplication and division (M), atomic instructions (A) and compressed (16-bit) instructions (C). That means it does not features an FPU, in which case it would have been an RV32GC core (and not RV32IMACFD) if both single and double-precision were supported.

Let’s check another one: Kendryte K210 dual-core RV64IMAFDC / RV64GC processor: that’s a 64-bit RISC-V processor (RV64I), with integer multiplication and division (M), atomic instructions (A), single-precision (F) and double-precision (D) floating-point (I + M+A+F+D = G), as well as compressed instructions (C).