In my 10th grade Summer, I took C++ course in Folsom Lake Community College. The Professor was teaching about how C++ code gets converted to Assembly language, how the assembler converts the Assembly instructions into Machine code then the CPU will execute the machine code. I got confused and asked my friends on what that means. My friends did not know it either. At home, my dad explained with a block diagram. I got more curious about the innerworkings and read the documentation of RISC-V instruction set. This led me to come up with MINERVA-8 a custom CPU 8 bit architecture.
MINERVA-8
MINERVA-8 (CUSTOM 8-BIT ASSEMBLY LANGUAGE) is a console-based 8-bit CPU simulator written in C++ that demonstrates how a processor executes instructions through the fetch-decode-execute cycle while showing changes to registers, memory, flags, and control flow.
The project includes a custom assembler that translates MINERVA-8 assembly language into machine code and loads the resulting instructions and data into 256 bytes of simulated RAM.
Architecture
MINERVA-8 currently includes:
- 8-bit CPU architecture
- 256 bytes of RAM
- Program Counter (PC)
- Register A
- Register B
- Carry Flag (CF)
- Zero Flag (ZF)
- Custom instruction set
- Custom assembler
- Symbolic labels
- Console display of CPU state and memory
- Numeric and character console output
Fetch-Decode-Execute Cycle
Fetch
The fetch unit uses the Program Counter to retrieve the next opcode from RAM.
Decode
The decoding unit determines which instruction the opcode represents and identifies any associated operand or memory address.
Execute
The execution unit performs the requested operation. Depending on the instruction, it can:
- modify registers
- perform arithmetic
- perform bitwise logic
- update CPU flags
- load or store memory
- change program control flow
- output values or characters
Instruction Set
Instruction DescriptionLDA
Load a value into Register A
LDB
Load a value into Register B
LDM
Load a value from memory into Register A
ADD
Add Register B to Register A
SUB
Subtract Register B from Register A
STA
Store Register A in memory
OUT
Output Register A as a number
OUTC
Output Register A as an ASCII character
JNZ
Jump if the Zero Flag is not set
JZ
Jump if the Zero Flag is set
JMP
Unconditional jump
AND
Bitwise AND of Register A and Register B
OR
Bitwise OR of Register A and Register B
XOR
Bitwise XOR of Register A and Register B
SHL
Shift Register A left by one bit
SHR
Shift Register A right by one bit
NOT
Invert every bit in Register A
INC
Increment Register A
DEC
Decrement Register A
CMP
Compare Register A and Register B and update flags
PUSH
Push Register A contents to stack
POP
Pop stack into Reg A and update flags
CALL
Call subroutine
RET
Return from subroutine to the caller
HLT
Halt execution
Comments 0
No comments yet. Be the first!
Sign in to join the conversation.