Inspiration

          When I was in grade 9 I watched Ben Eater create a computer from logic chips and my mind exploded. I realized computer architecture was just like LEGOs and that is how I spent my entire high school life doing. I wanted to create a computer better than Ben Eaters. His was an 8-bit computer was 16 bytes of RAM and 16 instructions. I needed to do something far better. So I began to design my first computer in grade 9 to grade 10 summer. This project is about my most recent creation. It is a 16 bit machine with many useful instructions. It is similar to Ben Eaters computer except that:



Understanding the Architecture in Words

Print the Instruction Set and the Block Diagram of the architecture, then read this and use that for reference.

   This architecture is linear. Once an instruction is finished the current address in the program counter is used as the location of the next instruction to execute. Some instructions manipulate the program counter themselves usually by the increment of the program counter or loading the program counter during jump instructions. There is no parallel computing or memory management but that is an area I would like to explore in the future. 

   A program is just a list of instructions that the computer follows exactly in the order you list them in. It has memory where you place the instruction and variables in. This computer has a RAM memory of  32768 Bytes and ROM memory of 4096 bytes.  Something different about this computer is that instruction codes are made of sometimes 1 or 3 bytes but for the most part, most instructions need 2 bytes. The first byte is always an instruction. The address larger than the first byte stores the operand and the number of operands is dependent on the micro code of the computer which is explained later or can be found in the pictures section(entire assembly language I made).

    The computer distinguishes between RAM and ROM memory through logic gates explained in the memory section. When the computer is fully reset it will think that the first instruction is stored at memory address 0. If we have a program already stored starting from address 0, it will begin to execute. 


   To understand how a computer like this executes we must look at something called the instruction cycle. The instruction cycle consists of 3 main steps. There is a state counter (decade counter), counting at a frequency that sets the speed of the CPU.  It resets when it reaches 16 or gets a signal saying that an instruction is done executing and does not need the full 16 states to complete. It just keeps track of which instruction state is active. State 1 on the counter represents fetch, state 2 represents decode, and 3 -16 all represent execution states. Execution states vary depending on state 1 and 2). The Control ROM takes input from the state counter and instruction register and outputs 32 control signals intended for all the components 1 step function that are hardwired in logic.


Instruction Cycle

Fetch

The state counter is at state 1, which signifies to the control ROM that it is the fetch state. When the control ROM sees that the computer is in its fetch state it will do the following no matter what. 

The contents of the Program Counter are read by the MAR.

*Clock step*

Decode

The state counter is now at state 2, which signifies to the control ROM that it is the decode state. When the control ROM sees that the computer is in its decode state it will do the following no matter what:

The contents of RAM that are stored into the address of the MAR are read by the Instruction Register. Also the program counter is always incremented.

*Clock Step*

Execute

This is where all the magic of the computer happens. In summary, fetch and decode can be thought of as a mesh of hardwired logic and ROM firmware acting as the Control Unit of the computer. 

The control ROM takes input from the state counter and the instruction register. This makes a 2-D array of instruction states which is what you see on the majority’s instruction set. The output of the control ROM is 32 bits wide and every control signal of every component of the computer is connected to the output of this ROM. What you see on the table is which components control signals are active. You give the computer a list of instructions each numbered from 0 and up. If there are loops in your program the numbers given to each instruction on the list can be used as a reference as to where to “jump” to.  


Execution Unit

The ALU is a chain of four 74181 4-bit ALUs 

The comparator is two 74682 comparators

This unit is capable of 48 Arithmetic & Boolean functions as well as compare if equal & not equal on two 16-bit words. I know it is possible to generate flags for greater than & less than, but I have not yet figured out the logic LMAO help me. But there is a central register known as the A register. It is 16-bits wide and can read from the bus as well as write to the bus through a buffer. The A registers outputs are connected into the primary inputs of the ALU and the comparator.  There is also a B register which can only read data from the bus and is 16-bits wide. The B registers outputs are connected to the secondary inputs of the ALU. There is also an S register which can only read from the bus and is just 6-bits wide. The 74181 uses a total of 6 signals which determine what function the it is set to and the S register is what stores this value and feeds it into the ALU. There is no logic in the control unit that generates the signals necessary to control the ALUs functions. This means that the A, B , and S registers must be loaded with values using instructions prior to reading the answer of the ALU. Once the 3 registers are updated the answer is ready at the output of the ALU but stopped by a buffer which connects it to the bus. 

 In Ben Eaters computer, he had instructions called add and sub. My design has 48 functions so I decided to split Ben Eaters add and sub instructions into parts. His instructions loads B with a value from RAM with background logic setting the ALU to add, then moves the ALU's answer to A all in one instruction cycle.  If you take a look at the instruction set of my design, there are instructions that move the ALU's answer to a component of the computer.  This is not clock cycle efficient but I really don't care.  I just wanna write programs on my own machine.  This type of instruction choice gives the hardware aspect of the project some slack. Anyways there is also a C register which can only read data from the bus and is 16-bits wide. 

The C registers outputs are connected to the secondary inputs of the comparator. This allows A and C registers to be used as variables when comparing.  The comparator & the ALU both generate flags. The ALU generates the carry flag, and it goes high when the answer needs more than 16-bits to store the value.  The comparator generates the equal and not equal flags. Since the comparator is made up of two separate chips, determining the net magnitudes takes some logic to decode the true equal, not equal, lesser, and greater flag signals.  I decided to just decode the equal and not equal flags. In the future I will add the greater and lesser flag.  The three flags are then sent to a FLAG register which is 3-bits wide. It is used to store the flag state during an instructions such as "Compare" & instructions that used the ALU as a source to read data from(example: instructions 13, 1A, 40, 41, 42, 43, 45). Take a look at the instruction set and look at the columns that show the micro states. Those instructions are the only instructions that update the FLAG register.  The output of the FLAG register is sent to some decoding logic which intertwines with the instruction decoding unit and feeds the decoded output signal to a very special component called the Program Counter.


Stack Unit, Subroutines, Push/Pop, Recursion

    For a computer to support Calling a function (jumping to some address that represents the first address of code that executes a type of function), and Returning back to the original stream of code, there must be a hardware mechanism. This is where the Stack Pointer comes into play.


   The Stack Pointer is an 8-bit register that can read and write data to and from the bus. It has the ability to increment and decrement. The outputs of the register are also connected to the address inputs of the Stack RAM. This RAM is physically separate address space from the main 32KB of RAM and 4KB of ROM. The Stack RAM is memory fully dedicated to storing values in a Stack Type Data Structure. Analogous to stacking plates over one another. The only way to get the bottom plate it to remove the plates on top of it one by one. Since the Stack Pointer can read and write to and from the rest of the components on board the bus, it may allow for some interesting functionality’s that I still need to work through.

For now,  have come up with 2 functionalities for the Stack Hardware I use quit often.

   The first was mentioned earlier and is supporting the Call/Return Functionality. The Assembly Code I created has an instruction called Jump to Subroutine with OPCODE 2 in hex. There is also an instruction called Return with OPCODE 3 in hex.

Here is a detailed break down of the two instructions Micro States


Assembly 

This is the syntax I use when I write programs on lined paper:

//  = comment

%% = Address Reference Name 

@ = Address 

@i = Indirect Address

# =Literal  Boolean value

LD = Load

ST = Store

JMPD = Jump Direct

JMPI = Jump Indirect

JSR = Jump SubRoutine

RTN = Return

CMP = Compare

POP = Pop

PUSH = Push

A = Accumulator 

B = Arithmetic Register

C = Comparable Register

S = Select Function Register

ALU = Arithmetic Logic Unit

OUT = Output Port

IN = Input Port 

SP = Stack Pointer

PC = Program Counter

WRITE = Signal to update 7x6 LED Matrix Display

HALT = Stop Clock

BRE = Branch If A=C

BRN = Branch If A != C

BRC = Branch if Carry

f( ) = ALU function 

**************************************************

//Start at 1, Count to 10 and HALT 

%%First Program

LD S f(A+1)

ST # D1 @ Var

%%Loop

LD A @ Var

CMP A # D11

BRE @ Done

ST ALU @ Var

JMPD @  loop 

%%Done

HALT

****************************************************


Input and Output Devices

This computer has 1 Input Port and 1 Output Port. Each of which are 16-bits wide. One Output Device is fully supported within the Assembly Language I created. There is the LD LCDd and LD LCDs Type Instructions

LCDd = LCD data, LCDs =  LCD mode select


Subroutines Stored in ROM