SERV 1.4 is finally released. Actually, it has been out since October last year but I've been so busy that I never got around to make a proper write-up. So let's see what the latest version of the award-winning SERV, the world's smallest RISC-V CPU brings.
Everybody heard, about the QERV
Let's start with the big news. As you probably know if you are reading this, one of the major things that makes SERV so small is that it is bit-serial, i.e. the internal datapath operates on one bit per clock cycle. Over the years some people have commented that SERV is nice, but has a tad too high CPI (Cycles Per Instruction) for their particular use-case. One way to decrease the CPI is to handle more bits each clock cyce and several years ago I started theorizing what would happen if we optionally had a 2-, 4- or 8-bit internal datapath instead. The speed increase by widening the data path is pretty easy to calculate, but we weren't sure how much larger it would be. In a presentation at the RISC-V Summit in 2022 I made an estimate that a 2-bit datapath would make SERV 50% larger and that a 4-bit datapath would make SERV 150% larger than the 1-bit version.
![]() |
| Boy, was I wrong! Not the first time, but for once the real numbers were actually better than my predictions |
But it wasn't until 2024 that a colleague of mine started actually building a 4-bit variant. And to our great surprise it wasn't 150% larger than SERV but only 20% larger. That's a pretty good deal for a CPU that's 3-4 times faster. Since SERV already had a pretty clean separation between data and control paths, most of the code changes just required allowing the data path width to be parameterized instead of hard-coded to 1, but there are a few places where width-specific optimizations were applied to keep the size down.
The 4-bit version, called QERV (Q for Quad) is now fully integrated in the code base. This means you can change between SERV and QERV mode by just changing a parameter. Very convenient to test different trade-offs between size and speed.
What about HERV, the 8-bit mode then? It's pretty much there already, but I decided to wait until the next release before integrating it, to give it a bit more testing and hopefully apply a few more optimizations before then.
![]() |
| Indicative numbers as presented during the 2024 European RISC-V Summit |
Other optimizations
While the days of large improvements to SERV are probably behind us, it turns out there were still some smaller optimizations to be made. Branches, slt operations and shifts are now one cycle faster. And that's not all. One FF was removed! Not impressed? Well, I had to look at the SERV history and came to the conclusion that this is the first FF that has been optimized away in more than three years! So actually, it's a pretty big deal. There was also another optimization around how shift amount is handled that doesn't save any resources but should likely slightly lower the energy consumption. How much? No clue.
![]() |
| I think it's safe to assume that the days of major SERV optimizations are behind us |
Features and bugs
Another feature, which will only be relevant for simulations, is a brand new debugging module. Not a debugger like the ones you typically use over JTAG. No, this is purely a module that creates some signals that can be handy when looking at simulation waveforms, like register values and what kind of instruction that is currently executed. You would perhaps expect these kind of things to already exist in SERV, but due to the extremely condensed code base, it has always been pretty awkward to get this kind of information directly from the RTL.
On the software side, the SERV reference platform, Servant, now runs Zephyr 4.0. I would love to see support for other RTOSes as well, but Zephyr support is really what matters for most cases nowadays.
Speaking of software support, updating to the latest version of the RISC-V compliance suite brought some nasty surprises and two related issues were found.
The correct value of mstatus[mpp] for machine-mode is 11, but SERV had this set to 00. Earlier versions of the regression test suite never cared about these bits but once they did, some tests started failing.
Another change in the regression test suite was that it started reading the misa register. This register was technically unimplemented in SERV but the CSR matching logic caused it to return the contents of the mstatus register instead and writing garbage data to other CSRs which made things very confusing.
Ok, so those are bugs then? Weeeell, it depends on how you look at things. Yes, they are bugs in the sense that they do not conform to the specification for these CSR registers. On the other hand, SERV is quite explicit about only implementing the absolute minimum of CSR logic that is needed to run Zephyr and pass the compliance test suite. So if you try to read or write any other register you will most likely just get bogus data. Either way, both issues mentioned above are fixed and the compliance test suite passes again.
The future is unwritten
Since the release of SERV 1.4.0 a number of new fixes and features have already been implemented and more things are lined up. While it's too early to say exactly what will go into the next SERV release we hope to see 8-bit support (HERV), external interrupts, which is a much requested feature, RV32E/EC support, substantial speedups of some two-stage operations and hopefully more things. Anything else you would like to see? Just send some code or let's have a chat. There are certainly things I would like some help with.

























