8 ms·
Show HN: RISC-V core written in 600 lines of C89
- deleted 3y ago[deleted]
- rowanG077 3y agoThe Readme doesn't answer it but I struggle to see why you want a c implementation of an ISA.
- nly 3y agoSo you can compile and run it on any platform with a C compiler
- rowanG077 3y agoThat is just something you can do with C code. That is not a goal in itself. Why would you want to run a C ISA instead of just using a standard simulator? Why not use verilator + any of the open source RISC-V cores?
- LoganDark 3y agoBecause those are slower, more complex, and more difficult to understand?
- rowanG077 3y agoI doubt verilator is much slower. The speed of it is insane. They are indeed more complex and difficult to understand. But I fail to see how that is a criterium. I would very much rather include an industry standard library in comparison to something homegrown.
- LoganDark 3y ago> They are indeed more complex and difficult to understand. But I fail to see how that is a criterium. It's... not? Like, if you want to merely use an ISA, you don't need it to be simple or easy to understand, in fact tons of people pride themselves on making extremely high-performance RISC-V cores with OoOE and so on. But the reason why someone might want a C implementation of an ISA is different from the reason people might want to go implement an ISA in a real project: maybe they want a software simulator that is easy to understand for one reason or another, perhaps for learning or demonstration purposes, or just as a fun hobby project. These people wouldn't benefit from just pulling down Verilator or using one of the existing BATTLE-TESTED INDUSTRY-STANDARD PROFESSIONALLY-AUDITED HIGH-PERFORMANCE implementations because they literally don't care about any of those things. In any case, it's a fallacy to assume that every programming project out there has to address a need in order to have a place. https://justforfunnoreally.dev https://justforfunnoreally.dev
- rowanG077 3y agoYes a hobby/learning is a great reason, why not just start with that? I was simply wondering what the reason was. Maybe the author had an interesting need for a C implementation to do something. Me asking for the reason is not me saying it doesn't deserve to exist. I don't think you are arguing in good faith here.
- LoganDark 3y ago> why not just start with that? I'm not the one who started the thread. > I don't think you are arguing in good faith here. With that, this discussion is over.
- srgpqt 3y agoPerhaps this could be used to run sandboxed code. Game engines could safely run mods using something like this, ala QuakeC.
- mcraiha 3y agoFor modern game engine you most likely want WebAssembly support. e.g. Flight Simulator does that https://flightsimulator.zendesk.com/hc/en-us/articles/7662900486940-WASM-Support-FAQ https://flightsimulator.zendesk.com/hc/en-us/articles/766290...
- mnurzia 3y agoDefinitely. My motivation for writing this was to have a simple CPU for a virtual game console-like project. I decided to release it on its own, though.
- Farmadupe 3y agoConsidering it's allocation-free, maybe it's an ultralight/ simulator for checking large quantities of compiler output? (i.e no VM to create and destroy for every testcase) Or the same but for testing some verilog/vhdl CPU implemetation in a simulator? Or since it's only 500SLOC, maybe it's just for fun!
- detrites 3y agoNot sure if this was intended, but coming to this as someone vaguely aware of RISC-V, it's looking like a fantastic form of documentation for the ISA, that both describes and gives a way to play with it, but in an intuitive, even fun manner. Obviously this works best for someone who already knows C - but, given it's C89 mitigates against this aspect somewhat.
- rowanG077 3y agoA reference implementation would be in Verilog or VHDL.
- peterfirefly 3y ago'switch' is a really, really nice language construct that was fully implemented long before C89. Using lots of nested 'if's instead is not a good idea.
- sylware 3y agonested "ifs" are optimized out by compilers. Moreover in the latest horrible gcc extensions you have the case statement using a _not_compiler constant expression (you can find the usage of such horrible gcc extension in linux net code).
- mnurzia 3y agoThis was my one of my main justifications for making this design choice, in addition to the (in my opinion) overwhelming amount of break statements that would result from using switches. But more importantly, many of the "if" statements have non-constant or more complex expressions in them that aren't supported in switch statements in ANSI C.
- sylware 3y agoYep. And as you stated, it is important to stay as much as possible close to c89, because ISO is literaly doing planned obsolescence, but on a long time cycle (5-10 years). Hopefully risc-v will be a success, and all system components and interpreters of very-high-level languages will be rewritten in risc-v assembly and it will become actually very hard to do planned-obsolescence.
- hgs3 3y ago'switch' is good, but for VM's computed goto is better.
- KerrAvon 3y agodepends on the compiler implementation. modern compilers may be able to treat equivalent switch statements, gotos, and if/else statements pretty much the same
- sylware 3y agoA bigger implementation, but has 64bits support: https://bellard.org/tinyemu/ https://bellard.org/tinyemu/
- RobotToaster 3y agoIs this designed to be used with some kind of C to VHDL/verilog transpiler?
- RealityVoid 3y agoNot really, think of it like a... CPU emulator? Ish? You have registers as variables in the program. If you have register a1 and you are at an instruction adding 1 to it, it will add 1 to the variable representing a1. So on and so forth. This works because, well, memory operations are mostly(all?) a CPU does so this "core" takes the program and does the same kind of memory operations the silicon would do, only in SW.
- aportnoy 3y agoHow about a RISC-V disassembler in 200 lines of C99? https://github.com/andportnoy/riscv-disassembler/blob/master/das.c https://github.com/andportnoy/riscv-disassembler/blob/master...
- mnurzia 3y agoThis is really cool, thanks for sharing! Something like this would be a great tool to distribute with my emulator.
- garganzol 3y agoIt would be nice if you could put a link to that project to your README file. Both projects are very impressive, especially when seen in conjunction with each other.
- aportnoy 3y agoI mean, his simulator already has a disassembler contained within it, would just need to replace comments with print statements.
- sutterbutter 3y agoAs a total newb to programming, what am I looking at here?
- detrites 3y agoThere are several different types of CPU's, in two main classes, CISC and RISC. The difference is summarised by the first letter - "Complex" vs. "Reduced" - Instruction Set Computer. Or, what size "vocabulary" a CPU decodes. RISC-V is a type of CPU architecture (a set of plans for how to build one, not an actual CPU itself), that also happens to be open source. Anyone can build a RISC-V CPU without having to buy the rights to do so. (Many are.) This project is an emulation of a RISC-V CPU. A kind of virtual "reference" CPU in software. It can be used to compile code that can run on a RISC-V type CPU, and to help understand what's happening inside the CPU when it runs. It's written in C, which is and was a very fundamental programming language that's influenced the design of many other languages. It is a language that is very close the fundamental language CPU's natively decode and process. CPU's natively use a language referred to as "Assembly", but which actually has many varieties particular to each CPU design. Regardless of variety of CPU, assembly is usually is about as reasonably "close to metal" as it gets. It's literally communicating with the CPU directly in its own language. This makes it extremely fast to run, but laborious to code, and also somewhat "dangerous" in that with such low-level control, it's easy to mess things up. This project takes an input of a text list of RISC-V assembly instructions (a "program") and pretends to be RISC-V CPU with those instructions loaded into it and being run on it. Useful for understanding, prototyping and building a RISC-V program. CPU's are designed rather to run assembly that already "works", having been created programmatically (compiled or interpreted), by a higher level language that isn't going to give it things that make no sense (hopefully). So there is not usually a lot of provisioning done in the design of the CPU to make it easy to watch it and its state carefully at a low level and examine how your assembly program is working, or not working. Emulation eases this.
- dragonwriter 3y ago> CPU’s natively use a language referred to as “Assembly”, b Strictly, CPUs use machine code. Assembly targeting a particular CPU is a very thin more-human-readable abstraction around the underlying machine code, but it is not, itself, what the CPU executes. That’s why “assemblers” exist – they are compilers from assembly language to machine code (though, because assembly is a very thin abstraction, they are much simpler than most other compilers.)
- bjourne 3y agoWhy stick with c89? Can't think of any compilers that doesn't support c99 nowadays. The major benefit is that you can use uint8_t and friends directly and don't need to define your own wrapper types.
- boricj 3y agoFunnily enough, the file rv.h does use stdint.h if available and contains the following comment: > All I want for Christmas is C89 with stdint.h
- mnurzia 3y agoIt's more of a fun exercise, I guess. But I do have experience with at least one compiler that doesn't support C99: Zilog's ez80 C compiler. Back in the day I used to program my TI-84+ CE for fun[0], and the only C solution was a pretty bespoke C89-only compiler[1] distributed with a community toolchain[2], which has since switched to clang. It's somewhat irrational, but in the back of my mind it bugs me if the software I write can't run on platforms like that. [0] https://github.com/mnurzia/chip8-ce https://github.com/mnurzia/chip8-ce [1] http://www.zilog.com/docs/appnotes/pb0098.pdf http://www.zilog.com/docs/appnotes/pb0098.pdf [2] https://ce-programming.github.io/toolchain/ https://ce-programming.github.io/toolchain/
- contrarian1234 3y agoDid Visual Studio finally make the jump?! (you could always just compile it as C++ code though)
- bjourne 3y agoNope stdint.h has been in msvc for over 10 years. Other c99 features may be not supported though.
- jpfr 3y agoMSVC did a big rewrite of the C frontend around MSVC2013. I haven’t encountered C99 idioms that don’t work nowadays. Granted, I might not use every feature in my typical coding style…
- nevi-me 3y agoQuestion: do the implementation of single instructions compile to single instructions if targeting RISC-V with optimisations enabled? That would be really awesome if compilers realise what your code is doing and replace the implementations of instructions with those instructions.
- dbcurtis 3y agoYeah, well, the rock that breaks your pick in that scenario is copying all the processor state back and forth to/from the emulation model, including flag register bits, and also correctly handling exceptions and faults. Emulating the instruction’s happy path is just scratching the surface.
- sitkack 3y agoIn the guest, you trap on reading emulation state, so that the source of truth is the hardware. Rather than use something like KVM I wonder if you could run another child process and use P trace?
- duskwuff 3y ago> including flag register bits RISC-V doesn't have those. Compare+branch is a single instruction.
- mnurzia 3y agoNot really, my implementation isn't smart enough to guide compilers to the right solution. Trivial instructions, like xor, are of course recognized, but for example the 32x32 mul implementation isn't. Maybe compilers will be smart enough one day... https://godbolt.org/z/WEcTzKf7M https://godbolt.org/z/WEcTzKf7M
- charcircuit 3y agoThis isn't a RISC-V core. It is a RISC-V emulator library.
- bitwize 3y agoI feel myself descending into old-fartitude more and more with every year. My wife and I were recently involved in a car accident (no one was hurt). While I was being checked out I overheard a 20-year-old firefighter exchange Facebook information with an 18-year-old EMT. I was like, "wait a minute, you guys seem really young and you still use Facebook? I thought Facebook was for your grandparents and all the kids now use Snapchat or TikTok?" I get that same feeling now. This kid is 20 and still using C89? Shouldn't people his age have been reared entirely in the crystal-spires-and-togas utopia of Rust, with raw pointers and buffer overruns being mere legends of their people's benighted past told to them by their elders? It's kind of comforting to see young programmers embracing the old ways, even if it's for hack value only.
- sitkack 3y agoI think kids or at least there’s the risk of kids seeing old people romantically reenacting their eight bit micro days and think that it’s some thing besides nostalgia. I was kind of the opposite as a kid, if it wasn’t crazy futuristic I didn’t want it. So even in the 80s I wanted an FPGA accelerators in every machine.
- bitwize 3y agoIt's not just nostalgia. Those old computers really are fun to operate -- like an MGB is fun to drive -- in ways modern systems aren't, even if they are far less useful than a modern system. In fact it's now possible to take advantage of modern software tools on modern systems and push those old beasts to new heights they couldn't have possibly reached during their heyday.
- LoganDark 3y ago> even in the 80s I wanted an FPGA accelerators in every machine Mostly unrelated, but I recently discovered that you can buy TPUs, right now, as a consumer product, from https://coral.ai https://coral.ai. The stock firmware already allows you to run these things so hard they overheat, which is amazing. But yes, I also want FPGA accelerators.
- mnurzia 3y ago
- garganzol 3y agoSeeing the RISC-V instructions implemented in the emulator like that, it comes to my mind that RISC-V is really a reduced instruction set CPU. When compared to AVR 16-bit RISC instruction set, RISC-V looks so much simpler. (You may be indirectly familiar with AVR architecture by the household name "Arduino".) The intriguing part is that AVR is just a microcontroller, while RISC-V is intended to be a full-blown CPU.
- opencl 3y agoThe base instruction set is tiny but there are quite a few extensions and pretty much every practical implementation includes at least a few of them. i.e. the GD32V microcontrollers implement RV32IMAC, Allwinner D1 which is a "full-blown" CPU meant to run Linux implements RV64IMAFDCVU. RV32I/RV64I are the base 32/64 bit integer instruction sets and every letter after that is a different extension. Most of the extensions are relatively small and simple, but the C (compressed instructions) extension introduces some decoder complexity and the V (vector) extension adds several hundred instructions. Though even with all the extensions it is still a very small/simple ISA by modern standards.
- staunton 3y agoPretty much all architectures have "simple" instruction sets under the hood, that is, the microcode that executes the mess we put in binaries. RISC-V is based on the idea that you can skip most of this step. The difficulty is getting fusing and other optimizations to work so the throughout remains high, which seems to work so far.
- freecodyx 3y agoThis proves that at the core. The things we rely on to achieve great software and life impacting technologies are extremely simple. The complexity is that how to make them.
- arcticbull 3y agoThe core concepts are generally very straightforward, however it's always the optimization that adds complexity. That's how you get the orders of magnitude improvement. This C89 core definitely doesn't do macro op fusion for instance.
- freecodyx 3y agoBy complexity, i meant the hardware it self. Not even the architecture or the instructions set. For example you can design a virtual machine in days. But making a real one is at the core of the geopolitical issues we have today
- numpad0 3y agoThe complexity is in how to distribute dev workload and how to make it financially viable. No one pays for beautiful works of art unless it’s somehow anchored, tangled and aligned into their interests.
- userbinator 3y agoBesides not using a switch() for the main instruction decode, there's nothing surprising here. Anyone who has worked with emulators before will find this code straightforward to read. RISC-V really is the new MIPS.