RISC-V Bases and Extensions Explained

Orange Pi Development Boards

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.

RISC-V Extensions RV64GC

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).

Support CNX Software - Donate via PayPal or become a Patron on Patreon

22
Leave a Reply

avatar
7 Comment threads
15 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
10 Comment authors
John C.dgpbluDavid WillmoreDeets Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
David Willmore
Guest
David Willmore

Good summay, thank you!

Laurent
Guest
Laurent

That will be nice if all these extensions are kept under control and properly supported by tools. If not, welcome to hell. I have bad memories of the mess MIPS was. The R5900 of the PS2 Linux was only supported by old tools and that was a pain.

dgp
Guest
dgp

The hell you speak of already exists. Almost all SoCs contain some common IP block with the registers messed with, totally reordered or otherwise broken. This means almost every driver for something that should just work has to manage a bunch of quirks and magic values. Then you have the tens or hundreds of differing interrupt controllers, bus interconnects etc.

At least the RISC-V isa extensions are discoverable at runtime (misa register), can optionally be turned off (misa can be writable) and orthogonal.

RK
Guest
RK

> This means almost every driver for something that should just work has to

There’s nothing unusual or uncommon about this in the general driver world. Plenty of peripherals and components come with a dozen different revisions and are all handled by the same driver.

Even at the user facing level I’m currently writing this reply on a CPU core that is at its third or fourth microcode revision, with the 5th bios firmware update and at the 2nd out of 4 PCB revisions. And this laptop been on the market for 3 years…

The fact It’s now done on the core level is really not a big deal and will barely be felt on the code-base.

dgp
Guest
dgp

>There’s nothing unusual or uncommon about this in the general driver world.

and it’s not a good thing. 😉

>Plenty of peripherals and components come with a dozen different revisions
>and are all handled by the same driver.

Take a look in drivers/usb/host in Linux. Notice how many something-hcd.c files there are in there.
A few of those are drivers for “ehci” controllers that are so messed up by the IP vendor that they don’t just work with the generic ehci driver and are an exact copy of it from sometime in Linux 3 with a bunch of hacks to make it work. Then take a look at drivers/usb/musb .. There are multiple glue layers and fudges for a single IP block.
A lot of drivers in the Linux source have ways to override the register read/write functions because just reading a register apparently isn’t something SoC vendors could come up with a standard for. There’s so much bloat and wasted effort that’s caused by SoC vendors obfuscating their hardware for no good reason.

>The fact It’s now done on the core level is really not a big deal and will barely be felt on the code-base.

It’s not a new thing. ARC, Xtensa and others are the same deal where you can configure the IP block and drop it into your design. That’s fine for embedded stuff where the only code that ever runs on it is yours.

Laurent
Guest
Laurent

I perhaps wasn’t clear enough 🙂

I’m talking about the possible lack of tools (assembler, compiler) for the CPU. If you don’t have that you won’t be able to discover anything at runtime, and you won’t be bothered by your undocumented IP because you won’t be able to build programs that support all of your CPU.

dgp
Guest
dgp

The extensions are optional so theoretically if you only target the base instruction set you will be able run some code and then check if the extensions exist. I think vendors shipping buggy or intentionally broken implementations that require special compiler versions to generate working code will be a bigger problem.

blu
Guest
blu

I cringe to this day at the memory of how gcc had ‘supported’ the paired-singles SIMD extension of the ppc750cxe/cl — it was being shadowed by the support for another extension, and so to get 750cxe/cl’s paired singles one had to build gcc with a very ritualistic set of flags.

blu
Guest
blu

An apt summary, Jean-Luc! What puzzles me is how some vendors don’t bother giving this information up front in their product briefs, as if labeling their product ‘n-bit RISC-V’ is sufficient to allow their customers make informed decisions. Luckily other RV players are well aware of the importance of the ISA for a CPU they’re selling.

Member
Michael Regenmacher

I can’t see any problem with such a lot of extensions because they are all orthogonal. Any risc-v designs can do ALL extensions – may be some of them via an „illegal instruction interrupt“.

blu
Guest
blu

> Any risc-v designs can do ALL extensions – may be some of them via an „illegal instruction interrupt“.

That’s a bit like saying it’s turing-complete, no? : )

Chances are that if I’m looking for a MCU part that does mul/div, one that does it via a trap might not be what I’m looking for.

dgp
Guest
dgp

>Chances are that if I’m looking for a MCU part that does mul/div,

MCUs usually have pin compatible series with a low end eco parts and a premium parts because redesigning a board if you need a few more k of flash is a real pain. So I imagine if RISC-V mcus take off past off-brand Chinese parts you’ll be able to get both. And both will be the same die just with the misa bits adjusted by laser or blowing some e-fuse.

Member
Michael Regenmacher

No problem with this. If you need this choose the right architecture (i.e. rv32im or above)

blu
Guest
blu

I was referring to the ‘any RV implementation doing all extensions’ statement, thus my counter example to that.

David Willmore
Guest
David Willmore

ARM soft vs hard float as an example? Sure, there’s an emulator for hard float in the kernel, but trapping illegal instructions and emulating them is a good deal slower than just using inline float emulation and skipping that trip through kernel land.

blu
Guest
blu

Yes, that’s a good example. In situations where a missing feature is needed and you have full control of the code, it makes much more sense to implement the feature manually/by lib/by compiler, rather than rely on invalid-op emulation , which is the slowest possible approach.

dgp
Guest
dgp

>it makes much more sense to implement the feature manually/by lib/by compiler

If the only concern is performance which it probably isn’t if you’re using floats but spec out an MCU that doesn’t have those extensions. If you do it via a trap the floating point emulator can be in the “utility ROM” that a lot of MCUs have now. If you have intentionally spec’d a more basic MCU into your project it’s likely it’s because you have a hard limit for the BoM cost and probably don’t want GCCs soft float library pushing your code size up to the next flash tier.

dgp
Guest
dgp

Doing it via a trap means you can use the same binaries for both situations though.
It’s probably a pretty rare case but in MCU land maybe you have a cost reduced version of your product that uses a slightly cheaper version of the MCU without hard floats. If you have the emulation in the RTOS you can run the same binaries on both versions. Libraries like the Apple Homekit ADK ship as binaries so they have to generate 20 different versions for ARM alone. I wouldn’t want to be the guy responsible for validating all of those.

Aaron
Guest
Aaron

That means it does not features an FPU, in which case it would have been an RV32IG core (and not RV32IMACFD)

It would actually be RV32GC, just like the example you gave below for RV64GC

Deets
Guest
Deets

Here’s the ESP32-S2 ULP:
The ULP co-processor implements RISC-V architecture that has the following features:
• Support for IMC instruction set
• Thirty-two 32-bit general registers
• 32-bit multiplier and divider
• Support for interrupts
• Boot by the CPU, or its dedicated timer, or RTC GPIO

John C.
Guest
John C.

This is no more informative than the risc-v docs. Very lazy article.