Skip to content

HDrizzle/stack_machine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

67 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Overview

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.

Program instructions

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):

  1. 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.
  2. WRITE - Writes instruction bits 4 - 11 to the bus. Bits 12 - 15 address the device to read from it.
  3. GOTO - Saves the 2 execution pointer GOTO latches (each of them are 1 byte) to the program counter
  4. GOTO-IF - Reads the LSB of the value in the goto decider latch and does a GOTO only if it is 1, otherwise does nothing
  5. HALT - Stops the clock, usefull for debugging
  6. CALL - Effectively the same as GOTO 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 each RETURN instruction when it is used.
  7. RETURN - The program counter will be set to the return address popped off the top of the call stack.

Bus

Up to 15 devices can read the bus and 16 write to it. Devices that can read the bus:

  1. NONE - Nothing reads this so that bytes can be popped from the stack without them going anywhere.
  2. STACK-PUSH - Stack controller (Push)
  3. ALU-A - ALU latch A
  4. ALU-B - ALU latch B
  5. GOTO-A - Control unit - Program counter GOTO latch A (first byte)
  6. GOTO-B - Control unit - Program counter GOTO latch B (second byte)
  7. GOTO-DECIDER - Control unit - GOTO decider latch (For GOTO-IF)
  8. GPRAM - GPRAM - Write
  9. GPRAM-INC-ADDR - GPRAM - Write ( address)
  10. GPRAM-ADDR-A - GPRAM - Address bits 0 - 7
  11. GPRAM-ADDR-B - GPRAM - Address bits 8 - 15
  12. GPIO-WRITE-A - Writes to GPIO output pins 0 - 7
  13. OFFSET-WRITE - Replaces value in stack at ToS - offset
  14. SET-STACK-OFFSET - Sets the stack offset byte
  15. ALU-C-IN - ALU latch for carry and borrow
  16. GPIO-WRITE-B - Writes to GPIO output pins 8 - 15

Devices that can set the state of (write to) the bus:

  1. STACK-POP - Stack controller (pop)
  2. OFFSET-READ - Reads value from stack at ToS - offset
  3. ALU - ALU output
  4. Control unit instruction bits 4 - 11, used for the WRITE instruction
  5. GPRAM - GPRAM - Read
  6. GPRAM-INC-ADDR - GPRAM - Read ( address)
  7. GPRAM-ADDR-A - GPRAM - Address bits 0 - 7
  8. GPRAM-ADDR-B - GPRAM - Address bits 8 - 15
  9. GPIO-READ-A - Reads GPIO input pins 0 - 7
  10. CLK-COUNTER-A - Lower byte of clock counter
  11. CLK-COUNTER-B - Upper byte of clock counter
  12. GPIO-READ-B - Reads GPIO input pins 8 - 15

The Stack

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:

  1. Push and Pop
  2. Using the current ToS pointer - stack offset (OFFSET-WRITE and OFFSET-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.

Call stack

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.

ALU

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 0s except for the result which is the LSB.

  1. ADD - Add
  2. ADD-C - Addition carry
  3. NOT - Bitwise NOT (latch A)
  4. OR - Bitwise OR
  5. AND - Bitwise AND
  6. XNOR - Bitwise XNOR, whether each pair of bits are equal
  7. SHIFT - Bitshifts A left by the first 3 bits of B
  8. EQ - Whether bytes are equal
  9. A - Contents of A latch
  10. B - Contents of B latch
  11. EXT-10 - Extension (not implemented)
  12. EXT-11 - Extension (not implemented)
  13. EXT-12 - Extension (not implemented)
  14. EXT-13 - Extension (not implemented)
  15. EXT-14 - Extension (not implemented)
  16. EXT-15 - Extension (not implemented)

Flow Control

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.

GOTO and GOTO-IF

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.

Function calling

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.

I/O

There are 16 input and 16 seperate output pins.

General purpose static-RAM (GPRAM)

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.

About

Design for a DIY computer

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published