Difference between revisions of "CPUProject"

From ATI public wiki
Jump to: navigation, search
m
m
Line 3: Line 3:
 
* Writing a compiler for it
 
* Writing a compiler for it
 
* Compiling GCC for this architecture
 
* Compiling GCC for this architecture
* Booting a light linux on it
+
* Booting a lightweight linux on it
  
 
= CPU Design=
 
= CPU Design=
Line 93: Line 93:
 
| 25|| JMPEQ || if EQ = 1: PC <-- Operand || Example || 00 000 0010 XX || ---- || ---- || if EQ=1 then Operand else PC_out+1  
 
| 25|| JMPEQ || if EQ = 1: PC <-- Operand || Example || 00 000 0010 XX || ---- || ---- || if EQ=1 then Operand else PC_out+1  
 
|-
 
|-
| 26|| ClearZ || Z <--- 0 || Example || 00 000 0010 XX || ---- || ---- ||  PC_out+1   
+
| 26|| ClearZ || Z <--- 0 || Example || 00 001 0010 XX || ---- || ---- ||  PC_out+1   
 
|-
 
|-
| 27|| ClearOV || OV <--- 0 || Example || 00 000 0010 XX || ---- || ---- || PC_out+1     
+
| 27|| ClearOV || OV <--- 0 || Example || 00 011 0010 XX || ---- || ---- || PC_out+1     
 
|-
 
|-
 
| 28|| ClearC || C <--- 0 || Example || 00 100 0010 XX || ---- || ---- || PC_out+1     
 
| 28|| ClearC || C <--- 0 || Example || 00 100 0010 XX || ---- || ---- || PC_out+1     
Line 113: Line 113:
 
| 35||Load_B_Mem || B <-- Mem[Operand] || Example || 11 000 0010 XX || ---- || Operand || PC_out+1     
 
| 35||Load_B_Mem || B <-- Mem[Operand] || Example || 11 000 0010 XX || ---- || Operand || PC_out+1     
 
|-
 
|-
| 36||Load_A_B || A <-- B || Example || ?????? || ---- || ---- || PC_out+1     
+
| 36||Load_A_B || A <-- B || Example || 00 000 ???? XX || ---- || ---- || PC_out+1     
 
|-
 
|-
| 37||Load_B_A || B <-- A || Example || ?????? || ---- || ---- || PC_out+1     
+
| 37||Load_B_A || B <-- A || Example || ?? 000 ???? XX || ---- || ---- || PC_out+1     
 
|-
 
|-
| 38||Load_Ind_A || A <-- M[A] || Example || ?????? || ---- || ---- || PC_out+1     
+
| 38||Load_Ind_A || A <-- M[A] || Example || 00 000 0011 00 || ---- || A || PC_out+1     
 
|-
 
|-
 
| 39|| PUSH || Mem [0 + SP] <--- A,SP <--- SP + 1 || Example || 00 000 0010 XX || ---- || SP || PC_out+1   
 
| 39|| PUSH || Mem [0 + SP] <--- A,SP <--- SP + 1 || Example || 00 000 0010 XX || ---- || SP || PC_out+1   
Line 168: Line 168:
 
! B_MUX !! Flags !! ALU command || ALU_MUX
 
! B_MUX !! Flags !! ALU command || ALU_MUX
 
|-
 
|-
| 2 bits ||  3 bits  || 5 bits || 2 bits
+
| 2 bits ||  3 bits  || 4 bits || 2 bits
 
|-
 
|-
 
|}
 
|}
Line 212: Line 212:
 
! !! command !! operation
 
! !! command !! operation
 
|-
 
|-
| 1 ||  00000   || A + B
+
| 1 ||  0000   || A + B
 
|-
 
|-
| 2 ||  00001   || A - B
+
| 2 ||  0001   || A - B
 
|-
 
|-
| 3 ||       ||  
+
| 3 || 0010  ||  
 
|-
 
|-
| 4 ||       ||  
+
| 4 || 0011  ||  
 
|-
 
|-
| 5 ||       ||  
+
| 5 || 0100  ||  
 
|-
 
|-
| 6 ||       ||  
+
| 6 || 0101  ||  
 
|-
 
|-
| 7 ||       ||  
+
| 7 || 0110  ||
 +
|-
 +
| 8 ||  0111  ||
 +
|-
 +
| 9 ||  1000  ||
 +
|-
 +
| 10 ||  1001  ||
 +
|-
 +
| 11 ||  1010  ||
 +
|-
 +
| 12 ||  1011  ||
 +
|-
 +
| 13 ||  1100  ||
 +
|-
 +
| 14 ||  1101  ||
 +
|-
 +
| 15 ||  1110  ||
 +
|-
 +
| 16 ||  1111  ||
 
|}
 
|}
 
For addition/subtraction a ripple carry model is made out of chain of full adders.  
 
For addition/subtraction a ripple carry model is made out of chain of full adders.  
Line 230: Line 248:
 
===Flags===
 
===Flags===
 
In DPU has the following flags:
 
In DPU has the following flags:
* Zero Flag (Z): will be set if the result of the operation is zero
+
* '''Zero Flag (Z)''': will be set if the result of the operation is zero
* Overflow Flag (OV): will be set if an overflow happens in signed operations (as an example if we have 8 bit addition of 82+91 the answer we expect is 173 but the result would be interpreted as -45). Overflow flag can be realized in the following way:
+
* '''Overflow Flag (OV)''': will be set if an overflow happens in signed operations (as an example if we have 8 bit addition of 82+91 the answer we expect is 173 but the result would be interpreted as -45). Overflow flag can be realized in the following way:
* Carry Flag (C): will be set if the unsigned addition or subtraction results in a carry.  
+
* '''Carry Flag (C)''': will be set if the unsigned addition or subtraction results in a carry.  
  
== Control unit==
+
To clear flags,the following commands are used in DPU command:
[[File:ControllerFSM.png|300px|thumb|right]]
+
{| class="wikitable"
[[File:InstDec.png|300px|thumb|right]]
+
|-
Control unit has four states:
+
! !! command !! FlagToClear
* Fetch: fetches the instructions from instruction memory and loads it in Instruction Register (IR)
+
|-
* Decode: decodes the information in IR
+
| 1 ||  001  || Clear Z
* Execute: if execution on DPU is needed the proper control signals would be provided, otherwise DPU will stay IDLE
+
|-
* WriteBack: in case there is a need to write a data into memory it will happen in this stage. All changes in Program Counter(PC) is happening here so all conditional and unconditional branching would be decided in this state. in case the instruction is HALT the PC would be frozen.
+
| 2 ||  011  || Clear OV
 +
|-
 +
| 3 ||  100  || Clear C
 +
|-
 +
|}
  
 
== Instruction Memory (ROM) ==
 
== Instruction Memory (ROM) ==
Line 247: Line 269:
 
   
 
   
 
== Data Memory ==
 
== Data Memory ==
[[File:DataMem.png|400px|thumb|right]]
+
[[File:DataMem.png|300px|thumb|right]]
 
Data memory has the following interface:
 
Data memory has the following interface:
 
* Address
 
* Address
Line 257: Line 279:
  
 
There is a stack is at the top of data memory and its size is not restricted.   
 
There is a stack is at the top of data memory and its size is not restricted.   
 +
 +
== Control unit==
 +
[[File:ControllerFSM.png|300px|thumb|right]]
 +
[[File:InstDec.png|300px|thumb|right]]
 +
Control unit has four states:
 +
* '''Fetch''': fetches the instructions from instruction memory and loads it in Instruction Register (IR)
 +
* '''Decode''': decodes the information in IR
 +
* '''Execute''': if execution on DPU is needed the proper control signals would be provided, otherwise DPU will stay IDLE
 +
* '''WriteBack''': in case there is a need to write a data into memory it will happen in this stage. All changes in Program Counter(PC) is happening here so all conditional and unconditional branching would be decided in this state. in case the instruction is HALT the PC would be frozen.
  
 
== Functional Testing ==
 
== Functional Testing ==
Line 267: Line 298:
 
== Future plans ==
 
== Future plans ==
 
The following are the future plans for CPU:
 
The following are the future plans for CPU:
* implementing load_A_B and Load_B_A
+
* Implementing load_A_B and Load_B_A
 +
* To fix clear OV code to 010
 +
* Fixing the size of data memory as a memory block and do a memory map to multiple instances of the block
 
* Adding indexed data addressing: A <--- M[A]  
 
* Adding indexed data addressing: A <--- M[A]  
 
* Adding indexed instruction addressing: PC <--- M[A]
 
* Adding indexed instruction addressing: PC <--- M[A]
 +
* implement barrel shift on acc
 
* Adding I/O
 
* Adding I/O
 
* Adding interupts  
 
* Adding interupts  
Line 279: Line 313:
  
 
= Assembler =
 
= Assembler =
 +
 
==Python Assembly translator==
 
==Python Assembly translator==
 
A simple assembly translator was designed to make debugging process faster. Here you can see 32 bit version of the code:  
 
A simple assembly translator was designed to make debugging process faster. Here you can see 32 bit version of the code:  

Revision as of 10:38, 6 December 2014

CPU project is one of the projects designed in department of computer engineering at TTU as a lab project. The main aims of this project are:

  • Developing a generic CPU without any fancy feature
  • Writing a compiler for it
  • Compiling GCC for this architecture
  • Booting a lightweight linux on it

CPU Design

Functionality Requirements

The CPU is supposed to be able to perform the following operations:

  • Addition/Subtraction
  • Increment/Decrement
  • Arithmetic and Logical Shift and Rotate through carry
  • Bitwise AND, OR, XOR and NOT
  • Negation
  • Load/Store
  • Unconditional Branch (jump)
  • Branch if zero / Branch if Overflow / Branch if Carry
  • Clear Registers/Flags
  • PUSH / POP
  • NOP/HALT

It can use these operations to build more sophisticated operations later.

Architecture

BlockDiagram.png

The architecture of this CPU is based on harvard architecture which has separate instruction and data memory. The instructions are assumed to be in the instruction memory before boot.

Instruction Format

Our CPU's instuction has 8 bit of upcode and one operand that can be as long as 32 bit. First 2 bits of OPcode are at the moment reserved.

Addressing Modes

The following Addressing modes are supported in out processor:

  • direct: program counter jumps to an address directly provided to it through instruction's operand
  • reletive: the program counter will jump to a location reletive to its current location
  • indirect: program counter will jump to an address stored in a memory location
  • register: program counter will jump to an address stored in a register
  • indexed: program counter will jump to an address stored in the memory with address stored in a register

Instruction Set (IS)

The following instrcutions designed for the CPU:

Instruction Register Transfer Language OpCode DPU Command Data To DPU MemAddress Next PC
1 Add_A_B A <-- A + B XX00 0000 00 000 0000 10 ---- ---- PC_out+1
2 Add_A_Mem A <-- A + Mem[Operand] XX00 0001 00 000 0000 00 ---- Operand PC_out+1
3 Add_A_Dir A <-- A + Operand XX00 0010 00 000 0000 01 Operand ---- PC_out+1
4 Sub_A_B A <-- A - B XX00 0011 00 000 0001 10 ---- ---- PC_out+1
5 Sub_A_Mem A <-- A - Mem[Operand] Example 00 000 0001 00 ---- Operand PC_out+1
6 Sub_A_Dir A <-- A - Operand Example 00 000 0001 01 Operand ---- PC_out+1
7 IncA A <-- A + 1 Example 00 000 0000 11 ---- ---- PC_out+1
8 DecA A <-- A - 1 Example 00 000 0001 11 ---- ---- PC_out+1
9 ShiftArithR A <-- A(7) & A(7 downto 1) Example 00 000 0111 00 ---- ---- PC_out+1
10 ShiftArithL A <-- A(7) & A(5 downto 0)& '0' Example 00 000 1000 00 ---- ---- PC_out+1
11 ShiftA_R A <-- A(6 downto 0)& '0' Example 00 000 1010 00 ---- ---- PC_out+1
12 ShiftA_L A <-- '0' & A(7 downto 1) Example 00 000 1011 00 ---- ---- PC_out+1
13 RRC A <-- C & A(7 downto 1) ,C<-- A(0) Example 00 000 1110 XX ---- ---- PC_out+1
14 RLC A <-- A(6 downto 0) & C ,C<-- A(7) Example 00 000 1111 XX ---- ---- PC_out+1
15 And_A_B A <-- A and B Example 00 000 0100 10 ---- ---- PC_out+1
16 OR_A_B A <-- A or B Example 00 000 0101 10 ---- ---- PC_out+1
17 XOR_A_B A <-- A xor B Example 00 000 0110 10 ---- ---- PC_out+1
18 FlipA A <-- not (A) Example 00 000 1100 00 ---- ---- PC_out+1
19 NegA A <-- not(A) + 1 Example 00 000 1001 00 ---- ---- PC_out+1
20 Jmp PC <-- Operand Example 00 000 0010 XX ---- ---- Operand
21 JmpZ if Z = 1: PC <-- Operand Example 00 000 0010 XX ---- ---- if Z=1 then Operand else PC_out+1
22 JmpOV if OV = 1: PC <-- Operand Example 00 000 0010 XX ---- ---- if OV=1 then Operand else PC_out+1
23 JmpC if C = 1: PC <-- Operand Example 00 000 0010 XX ---- ---- if C=1 then Operand else PC_out+1
24 Jmp_rel PC <-- PC + Operand Example 00 000 0010 XX ---- ---- PC <-- PC + Operand
25 JMPEQ if EQ = 1: PC <-- Operand Example 00 000 0010 XX ---- ---- if EQ=1 then Operand else PC_out+1
26 ClearZ Z <--- 0 Example 00 001 0010 XX ---- ---- PC_out+1
27 ClearOV OV <--- 0 Example 00 011 0010 XX ---- ---- PC_out+1
28 ClearC C <--- 0 Example 00 100 0010 XX ---- ---- PC_out+1
29 ClearACC ACC <-- 0 Example 00 000 1101 XX ---- ---- PC_out+1
30 LoadPC PC <---- A Example 00 000 0010 XX ---- ---- A
31 SavePC A <---- PC Example 00 000 0011 01 PC ---- PC_out+1
32 Load_A_Mem A <-- Mem[Operand] Example 00 000 0011 00 ---- Operand PC_out+1
33 Store_A_Mem Mem[Operand] <-- A Example 00 000 0010 XX ---- Operand PC_out+1
34 Load_B_Dir B <-- Operand Example 01 000 0010 XX Operand ---- PC_out+1
35 Load_B_Mem B <-- Mem[Operand] Example 11 000 0010 XX ---- Operand PC_out+1
36 Load_A_B A <-- B Example 00 000 ???? XX ---- ---- PC_out+1
37 Load_B_A B <-- A Example  ?? 000 ???? XX ---- ---- PC_out+1
38 Load_Ind_A A <-- M[A] Example 00 000 0011 00 ---- A PC_out+1
39 PUSH Mem [0 + SP] <--- A,SP <--- SP + 1 Example 00 000 0010 XX ---- SP PC_out+1
40 POP A <--- Mem [0 + SP - 1],SP <--- SP - 1 Example 00 000 0011 00 ---- SP - 1 PC_out+1
41 NOP NOP Example 00 000 0010 XX ---- ---- PC_out+1
42 HALT HALT Example 00 000 0010 XX ---- ---- PC

Implementation of complex instructions

the follwoing instructions can be also implemented with the ones in IS:

  • Call "function_name":
PUSH
SavePC
Push
Jmp "function address"
POP  
  • Return:
POP
Add_A_Dir 4
LoadPC
  • IndJMP "MemAddress":
PUSH
Load_A_Mem "MemAddress"
LoadPC

Note: its important to POP back the ACC value on the jump destination.

  • JmpB:
PUSH
Load_A_B
LoadPC

Note: its important to POP back the ACC value on the jump destination.

  • JmpIndx:
PUSH
Load_Ind_A
LoadPC

Note: its important to POP back the ACC value on the jump destination.

DataPath unit

DPU.png

Datapath unit includes an Arithmatic Logical Unit (ALU), one Accumulator(ACC) and one general purpose register(Register B) and 2 multiplexers along with the flags. The DPU command is formed as following:

B_MUX Flags ALU command ALU_MUX
2 bits 3 bits 4 bits 2 bits

ALU Multiplexer

The ALU multiplexer chooses the inputs according to the table bellow:

command output
1 00  ???
2 01  ???
3 10  ???
4 11  ???

B-Register Multiplexer

The B-register multiplexer chooses the inputs according to the table bellow:

command output
1 00  ???
2 01  ???
3 10  ???
4 11  ???

ALU

The ALU covers the following operations:

command operation
1 0000 A + B
2 0001 A - B
3 0010
4 0011
5 0100
6 0101
7 0110
8 0111
9 1000
10 1001
11 1010
12 1011
13 1100
14 1101
15 1110
16 1111

For addition/subtraction a ripple carry model is made out of chain of full adders.

Flags

In DPU has the following flags:

  • Zero Flag (Z): will be set if the result of the operation is zero
  • Overflow Flag (OV): will be set if an overflow happens in signed operations (as an example if we have 8 bit addition of 82+91 the answer we expect is 173 but the result would be interpreted as -45). Overflow flag can be realized in the following way:
  • Carry Flag (C): will be set if the unsigned addition or subtraction results in a carry.

To clear flags,the following commands are used in DPU command:

command FlagToClear
1 001 Clear Z
2 011 Clear OV
3 100 Clear C

Instruction Memory (ROM)

Instruction memory is a read only memory that user will fill in the beginning.

Data Memory

DataMem.png

Data memory has the following interface:

  • Address
  • Data
  • WrtEn
  • rst
  • clk

Writing into data memory takes one clock cycle but readingf from it can be done instantly(or in reletively shorter time). So we can assume that if we issue address in one clock cycle, we can get the data in the same clock cycle.

There is a stack is at the top of data memory and its size is not restricted.

Control unit

ControllerFSM.png

Control unit has four states:

  • Fetch: fetches the instructions from instruction memory and loads it in Instruction Register (IR)
  • Decode: decodes the information in IR
  • Execute: if execution on DPU is needed the proper control signals would be provided, otherwise DPU will stay IDLE
  • WriteBack: in case there is a need to write a data into memory it will happen in this stage. All changes in Program Counter(PC) is happening here so all conditional and unconditional branching would be decided in this state. in case the instruction is HALT the PC would be frozen.

Functional Testing

Following machine code program has been made to test functionality of all instructions. The test program doesnt cover all the cases but run through all the instructions.

Future plans

The following are the future plans for CPU:

  • Implementing load_A_B and Load_B_A
  • To fix clear OV code to 010
  • Fixing the size of data memory as a memory block and do a memory map to multiple instances of the block
  • Adding indexed data addressing: A <--- M[A]
  • Adding indexed instruction addressing: PC <--- M[A]
  • implement barrel shift on acc
  • Adding I/O
  • Adding interupts
  • Pipelining
  • Branch prediction
  • Synthesis and FPGA implementation
  • VGA controller?
  • Direct Memory Access (DMA)

Assembler

Python Assembly translator

A simple assembly translator was designed to make debugging process faster. Here you can see 32 bit version of the code:

import re
InstructionOpCode = {

                'Add_A_B':	"000000",
                'Add_A_Mem': 	"000001",
                'Add_A_Dir': 	"000010",
                'Sub_A_B':	"000011",
                'Sub_A_Mem':	"000100",
                'Sub_A_Dir': 	"000101",
                'IncA': 	"000110",
                'DecA':		"000111",
                'And_A_B':	"001000",
                'OR_A_B':	"001001",
                'XOR_A_B':	"001010",
                'FlipA':	"001011",
                'NegA':		"001100",
                'Jump':		"001101",
                'JmpZ':		"001110",
                'JmpOV':	"001111",
                'Jmp_rel':	"010000",
                'JMPEQ':	"010001",
                'ClearZ':	"010010",
                'ClearOV':	"010011",
                'LoadPC': 	"010100",
                'SavePC':	"010101",
                'ShiftArithR':	"010110",
                'ShiftArithL':	"010111",
                'ShiftA_R':	"011000",
                'ShiftA_L':	"011001",
                'Load_A_Mem':	"011010",
                'Store_A_Mem':	"011011",
                'Load_B_Dir':	"011100",
                'Load_B_Mem':	"011101",
                'JmpC':		"011110",
                'ClearC':	"011111",
                'ClearACC':	"100000",
                'RRC':	  	"100001",
                'RLC':		"100010",
                'PUSH':		"111100",
                'POP':		"111101",
                'NOP':		"111110",
                'HALT':		"111111",

}
AssemblyFile = open('Assembly.txt', 'r+')
MachineCodeFile = open('MachineCode.txt', 'w')
counter=0
for line in AssemblyFile:

    for key in InstructionOpCode:
        if key in line:
            operand= "00000000"
            if "Mem" in line:
                operand = re.findall(r'\d+',line)[0]
            elif "Jmp" in line:
                operand = re.findall(r'\d+',line)[0]
            elif "Dir" in line:
                operand = re.findall(r'\d+',line)[0]
            operand = "00000000"+"00000000"+"00000000"+ operand
            MachineCodeFile.write(str(counter)+ " =>   "+ "\"00"+InstructionOpCode[key]+operand+'\",'+'\n')
            counter +=1

MachineCodeFile.close()
AssemblyFile.close()

Java Assembler

Compiler