Desigining and building a computer from scratch
Annotated view of MiniBit version 2 (December 2016)
I've always been curious with how a computer works at a low level. A while ago, I learned x86 assembly and started to really get a grasp of what actually happens in the silicon. However, modern processors are very complex and while I understood what it was doing, I didn't know how it was doing it. I wanted a simpler device that I could completely understand.
I decided the only way to get that would be to make my own processor. The project also ended up being a great opportunity to learn digital electronics.
Currently, I have a semi-functional prototype built on about a dozen breadboards (image above). I've also replicated the digital electronics in Verilog and I'm using that to test modifications.
I wanted to use only simple integrated circuits in my design. If I could create it out of discrete transistors in theory, it was fair play.
At the current stage, there is no display and input is performed with a dip switch panel. I have plans to add I/O capabilities which could eventually be extended to work with a modified display or keyboard.
MiniBit is an 8-bit processor. Components are connected to an 8-bit data bus or a 2-bit control bus.
There are 8 registers of which 2 are general purpose.
There are 23 unique instructions. Opcodes are either one or two bytes long.
All instructions take 6 clock cycles to execute. The clock itself, can be incremented manually for debugging or set to run automatically. Speed is controlled with a potentiometer. I haven't yet tested the maximum processor speed.
Currently, RAM addresses are 8-bit and therefore there are 256 bytes of addressable memory. However, I have plans to expand to 16-bit addresses and therefore 64 KB of memory.
There is no ROM so all data is lost when powered off.
Here are a list of registers along with their function:
A - general purpose register, can read/write to data bus, first operand for the ALU
B - general purpose register, can read/write to data bus, second operand for the ALU
O (output) - output of ALU operations, can write to data bus
FL (flag) - written to by ALU operations, used in sequencer and ALU operation, stores the following bit flags:
CARRY - set if an operation overflows
LT (less than) - set if the most significant bit is set on output
NZ (not zero) - set if output of ALU is not zero
IP (instruction pointer) - holds the current instruction address, updated automatically by sequencer, writes to RAM address selector
M (memory) - holds custom data address, can read from data bus, writes to RAM address selector
INT (instruction) - holds currently executing instruction, set automatically in fetch-execute cycle, used as opcode reference
VAL (value) - holds optional second byte of opcode, can write to data bus
For the registers that can be programmed to interact with the data bus, the following two bit identifiers are used in opcodes:Write (
The ALU performs basic, 8-bit arithmetic operations on either one or both
B registers and stores the output in
Additionally, it stores operation flags in
FL that can be used in further instructions.
For instance, it is possible to use the carry flag to perform arithmetic operations on values of any size.
All ALU opcodes are of the type
111xxxxx and the lowest 5 bits are passed directly to the ALU as a secondary opcode.
The following operations are supported:
ADD - (A + B)
CADD - (A + B), use carry flag
SUB - (A - B)
CSUB - (A - B), use carry flag
INC - (A + 1)
NAND - (A NAND B)
BTL - (A << 1)
CBTL - (A << 1), use carry flag
BTR - (A >> 1)
CBTR - (A >> 1), use carry flag
The following instructions can be used to move data around:
Note: the symbols
bb represent the two bit register identifiers.
MOV aa, bb - moves the contents of aa to bb
STORE aa - stores the contents of aa in RAM at address M
FETCH bb - fetches the contents of RAM at address M into bb
LOAD bb, [val] (2 bytes) - loads an 8-bit value into bb
SAVE, [val] (2 bytes) - saves an 8-bit value into RAM at address M
INCM - increment the M register
DECM - decrement the M register
*Currently I/O operations are not implemented
DISP aa - display contents of aa on the bus until control signal is recieved
READ bb - read contents of bus into bb when control signal is recieved
HLT - halt until control signal is recieved
JMP, [val] (2 bytes) - unconditional jump to val
JLT, [val] (2 bytes) - jump to val if LT flag is set
JNZ, [val] (2 bytes) - jump to val if NZ flag is set
More info coming soon...