This is the design and specifications for an 8-bit stack-based computer processor designed to support programming in Reverse Polish Notation (RPN). The computer has a LIFO (Last In First Out) stack which stores individual bytes. The Top of Stack (ToS) will be a 16-bit pointer which can be incremented and decremented for Pushes and Pops. It will also be possible to read/write the stack below the ToS. There will be another piece of memory, the general purpose static-RAM (GPRAM), that will be sort of like the heap and can be written to and read from without hardware protection. I got the idea for this from my 1989 HP 48SX calculator which also uses RPN.
Each instruction will be 16 bits and interpreted by the control unit. The first 4 bits (0 - 3) of the instruction will address the below list of operations. The rest of the instruction (bits 4 - 15) may be ignored or used for different things depending on the specific operation.
Here's the current list of the operation codes (opcodes):
MOVE
- Bus usage - The rest of the instruction will be interpreted as follows: bits 8 - 11 address the device which will set the state of the bus and bits 12 - 15 will address the device to read from it. Bits 4 - 7 are sent to the ALU as it's opcode incase the data is comming from it.WRITE
- Writes instruction bits 4 - 11 to the bus. Bits 12 - 15 address the device to read from it.GOTO
- Saves the 2 execution pointer GOTO latches (each of them are 1 byte) to the program counterGOTO-IF
- Reads the LSB of the value in the goto decider latch and does a GOTO only if it is 1, otherwise does nothingHALT
- Stops the clock, usefull for debuggingCALL
- Effectively the same asGOTO
but also pushes the return address (current value of program counter) onto the call stack. Note: The return address can be copied as-is and does not need to be incremented because it will be incremented normally after eachRETURN
instruction when it is used.RETURN
- The program counter will be set to the return address popped off the top of the call stack.
Up to 15 devices can read the bus and 16 write to it. Devices that can read the bus:
NONE
- Nothing reads this so that bytes can be popped from the stack without them going anywhere.STACK-PUSH
- Stack controller (Push)ALU-A
- ALU latch AALU-B
- ALU latch BGOTO-A
- Control unit - Program counter GOTO latch A (first byte)GOTO-B
- Control unit - Program counter GOTO latch B (second byte)GOTO-DECIDER
- Control unit - GOTO decider latch (For GOTO-IF)GPRAM
- GPRAM - WriteGPRAM-INC-ADDR
- GPRAM - Write ( address)GPRAM-ADDR-A
- GPRAM - Address bits 0 - 7GPRAM-ADDR-B
- GPRAM - Address bits 8 - 15GPIO-WRITE-A
- Writes to GPIO output pins 0 - 7OFFSET-WRITE
- Replaces value in stack atToS - offset
SET-STACK-OFFSET
- Sets the stack offset byteALU-C-IN
- ALU latch for carry and borrowGPIO-WRITE-B
- Writes to GPIO output pins 8 - 15
Devices that can set the state of (write to) the bus:
STACK-POP
- Stack controller (pop)OFFSET-READ
- Reads value from stack atToS - offset
ALU
- ALU output- Control unit instruction bits 4 - 11, used for the
WRITE
instruction GPRAM
- GPRAM - ReadGPRAM-INC-ADDR
- GPRAM - Read ( address)GPRAM-ADDR-A
- GPRAM - Address bits 0 - 7GPRAM-ADDR-B
- GPRAM - Address bits 8 - 15GPIO-READ-A
- Reads GPIO input pins 0 - 7CLK-COUNTER-A
- Lower byte of clock counterCLK-COUNTER-B
- Upper byte of clock counterGPIO-READ-B
- Reads GPIO input pins 8 - 15
The stack will simply be a piece of memory seperate from the program memory and managed by hardware.
There will be two ways to access the stack:
- Push and Pop
- Using the current ToS pointer - stack offset (
OFFSET-WRITE
andOFFSET-READ
) (does not change ToS). The stack offset will be a 1-byte number set from the bus (SET-STACK-OFFSET
) and will not affect pushes and pops.
Whenever a "function" is called (using the CALL
instruction), the current program counter will be pushed onto the call stack. The call stack will be a seperate stack memory containing 256 (1 byte address size) 16-bit words. Each word will be a return address - where to set the program counter during a RETURN
instruction.
The ALU uses 2 8-bit latches for input and has 1 output. The specific operation it does is controlled by 4 bits (2^4 = 16 operations). All operations that result in a boolean output all 0
s except for the result which is the LSB.
ADD
- AddADD-C
- Addition carryNOT
- Bitwise NOT (latch A)OR
- Bitwise ORAND
- Bitwise ANDXNOR
- Bitwise XNOR, whether each pair of bits are equalSHIFT
- Bitshifts A left by the first 3 bits of BEQ
- Whether bytes are equalA
- Contents of A latchB
- Contents of B latchEXT-10
- Extension (not implemented)EXT-11
- Extension (not implemented)EXT-12
- Extension (not implemented)EXT-13
- Extension (not implemented)EXT-14
- Extension (not implemented)EXT-15
- Extension (not implemented)
In the actual machine code there are no such things as functions, loops, if-statements, etc. Instead, these will be converted by the compiler into instructions which explicitly set the program execution pointer.
A goto will first need to use the bus usage instruction (Instruction 0) twice to set both of the execution pointer A and B goto latches, probably comming from the stack. This is for returning from a function using the return address, but if calling a function, the compiler can just WRITE
the hardcoded values directly to the A and B latches. Then the GOTO instruction will be used which uses the A and B goto latches to set the execution pointer.
GOTO-IF: First, move a value into the control unit GOTO decider latch, then use the GOTO-IF instruction. This will do the same as the GOTO instruction described above ONLY if the LSB of the latch is 1.
Functions in the machine code are only defined by CALL
and RETURN
instructions. To call a function, make sure the correct pointer to the beginning of the function is stored in the control unit goto A and B latches. Then use the CALL
instruction which is basically a GOTO but will first put the current program counter value onto the call stack as the return address.
There are 16 input and 16 seperate output pins.
This piece of memory will not have any hardware protection like the stack and can be writen to and read from at any location. It will have a 16-bit address by 8-bit word size (65,536 bytes) just like the stack.
It's address latch can be optionally incremented upon reads/writes and can be directly set by 2 8-bit latches (GPRAM-ADDR-A
and GPRAM-ADDR-B
) from the bus. If the address is incremented, the read/write will happen first, then the incrementation.