5 ms·
Nice article! I would definitely recommend for everyone to write a CPU emulator at least once. It will give you a lot of perspective on how computers really wor
by charlesdaniels 6y ago
Nice article! I would definitely recommend for everyone to write a CPU emulator at least once. It will give you a lot of perspective on how computers really work. As someone else pointed out CHIP-8[0] is a good one that's not too complicated.
If you want something more "real", MIPS and RISC-V are also not too hard, if you just do a subset of the instruction set and not the whole thing. You can skip most of the instructions that deal in bytes and half-words. It's also easier to implement main memory as being word-addressable only (but this can introduce incompatibilities with real assembler programs).
I wrote a cycle-accurate, pipeline simulator for MIPS for a course, which totaled only about 1200 SLOC. If you didn't need to simulate all the pipeline registers (you probably don't) and use a higher level language, this is probably a <750SLOC project.
0 - https://en.wikipedia.org/wiki/CHIP-8 https://en.wikipedia.org/wiki/CHIP-8
- triyambakam 6y agoDo you have any suggested resources for learning to implement a CPU emulator, such as for RISC-V?
- cptnapalm 6y agoI just started doing a Chip-8 after finding this: http://www.multigesture.net/articles/how-to-write-an-emulator-chip-8-interpreter/ http://www.multigesture.net/articles/how-to-write-an-emulato... It seems to be well regarded.
- thethirdone 6y agoI'm not the person you asked, but I made an educational simulator for RISC-V [0]. The most critical resource even if it is not super convenient is the official RISC-V specification [1] (this is the latest draft as of writing this comment). There are a bunch of open source simulators [2] to look at for reference if you are unsure of how something is suppose to work. I would recommend compiling a C program to RISC-V and looking at disassembled machine code to get an idea for how things are normally done in terms of RISC-V assembly. There isn't any particularly nice documentation that I am aware of, but enough universities teach using it that there should be some resources that would be helpful for making a simulator. I can probably come up with some links if you are serious about making a simulator, but its a little too much effort to do for a drive-by comment. [0]: https://github.com/TheThirdOne/rars https://github.com/TheThirdOne/rars [1]: https://github.com/riscv/riscv-isa-manual/releases/download/draft-20200727-8088ba4/riscv-spec.pdf https://github.com/riscv/riscv-isa-manual/releases/download/... [2]: https://github.com/riscv/riscv-software-list#simulators https://github.com/riscv/riscv-software-list#simulators
- charlesdaniels 6y agoHey, thanks for making RARS! I am TA-ing a class this semester where we are using RARS. It's my university's "build a CPU with Verilog class", and we just switched to RISC-V. We previously used MIPS with MARS, and lacking a MARS alternative was one of our blockers for switching to RISC-V.
- jhallenworld 6y agoWell I have an important resource for this, the book "Hacker's Delight": https://www.amazon.com/Hackers-Delight-2nd-Henry-Warren/dp/0321842685 https://www.amazon.com/Hackers-Delight-2nd-Henry-Warren/dp/0... This book will tell you how to efficiently generate condition flag values such as carry and overflow. It's easy when when you have extra bits available (such as emulating an 8 or 16 bit processor on a 32-bit processor), but less obvious when you are emulating a 32-bit processor on a 32-bit processor from a high level language.
- charlesdaniels 6y agoI don't have a specific suggestion for learning to make CPU emulators in particular. As thethirdone said in his comment, the official specification is the most important resource. The actual body of the simulator is mostly going to be a lot of lookup tables. You'll probably have a struct or class that stores the state of the CPU at a specific instant in time. Your main loop will be calling a next_state() function on that object. For your sanity, I would highly suggest making your state object immutable. I have found breaking out the ALU, instruction decoder, and control logic into separate functions is a good way to split things apart.
- pizza234 6y agoIt ultimately depends on the level of abstraction ("emulating a CPU" is ambiguous): emulating the logical gates of a CPU is an entirely different matter from emulating the instruction set; besides, generally one emulates an entire system, not just the CPU. If you're looking for the former, the canonical course is "NAND2Tetris". If you take the class on Coursera, the first (of two parts) covers the hardware. I've also seen two very interesting books, but I haven't read them - "The ZX Spectrum Ula: How to Design a Microcomputer", and "Designing Video Game Hardware in Verilog". Courses at this level are generally exactly defined. In the second case - emulating at the ISA level, the canonical entry is to emulate a CHIP-8, since it's simple and relatively well defined. At this level, targets are rarely exactly defined. CHIP-8 for example is well-defined in theory, however, for example, looking at the Wikipedia page won't suffice, because there are many extensions. Additionally, CHIP-8 has no standard clock speed. But it's easy to find the resources, and you can end with an exactly working system (the same can't be easily say, for example, of a NES or a C64 - you'll find conflicting information).
- Akronymus 6y ago> If you want something more "real", MIPS and RISC-V are also not too hard,... I personally think that MIPS is just not relevant enough in the real world anymore to deserve being taught at school. But I do get that there already is a lot of material out there. I'd personally go with a risc-v subset at first and expand on it.
- charlesdaniels 6y ago> I personally think that MIPS is just not relevant enough in the real world anymore to deserve being taught at school. But I do get that there already is a lot of material out there. From a pedagogy perspective, the course materials / textbooks haven't really caught up yet. Also, the project I was referring to was in an Architecture class; I would contend that the underlying concepts of how a pipeline works can be taught pretty much any architecture. MIPS is easy to understand, which makes it well suited for teaching. That said, at my university, we are slowly transitioning to RISC-V, so hopefully within a few years it will have propagated to all of the courses.