Simulating RISC-V in C++ for my better understanding of c++ and computer architecture.
src/simulator.cppstarts the simulator and connects the parts together.include/alu/alu.hppdeclares arithmetic operations.src/alu/alu.cppimplements arithmetic operations.include/cpu/cpu.hppdeclares the CPU state.src/cpu/cpu.cppimplements CPU behavior such as program counter updates.include/decoder/decoder.hppdeclares machine-code decoding.src/decoder/decoder.cppdecodes a small RV32I instruction subset.include/instruction/instruction.hppdeclares the temporary instruction model.src/instruction/instruction.cppimplements instruction helper constructors.include/memory/memory.hppdeclares simulated byte-addressed memory.src/memory/memory.cppimplements 32-bit word memory reads and writes.include/program/program.hppdeclares a simple instruction container.src/program/program.cppimplements instruction fetch by address.include/register/registers.hppdeclares the register file.src/register/registers.cppimplements register read, write, and dump behavior.Makefilebuilds and runs the project with simple commands.
- The CPU owns the register file.
- The CPU owns simulated memory.
- The CPU also stores the program counter, usually called
pc. - In RV32I, normal instructions are 4 bytes, so the default
pcstep ispc += 4. - The CPU asks the ALU to perform arithmetic, then writes the result back to a register.
- An instruction describes one operation the CPU should perform.
addiuses a signed immediate, so values like-5are allowed.- The decoder turns real machine-code bits into this instruction structure.
- The decoder currently supports
add,sub, andaddi. - It also supports
lwandswfor 32-bit word memory access. addandsubare R-type instructions.addiis an I-type instruction with a signed 12-bit immediate.lwis an I-type load instruction, andswis an S-type store instruction.- Unsupported instruction words throw an error for now.
- Memory is byte-addressed, meaning each address points to one byte.
lwloads 4 bytes from memory into a register.swstores 4 bytes from a register into memory.- For now, word addresses must be divisible by 4.
- A program is a list of instructions stored in order.
- The CPU uses
pcas an address, so instruction0is at address0, instruction1is at address4, instruction2is at address8, and so on. Cpu::run(...)keeps fetching and executing instructions until there is no instruction at the currentpc.- Passing
truetoCpu::run(program, true)enables a trace that prints each fetched instruction and its effect.
- ALU means arithmetic logic unit.
- For now, this project supports only
add,sub, andaddistyle behavior. - These are not decoded from real machine code yet; they are direct C++ function calls for learning.
- RV32I has 32 integer registers:
x0tox31. x0is hardwired to zero, so writes tox0are ignored.- Registers also have ABI names, such as
zero,ra,sp,a0, andt0.
make
make runTo remove generated build files:
make clean