Categories
Uncategorized

Simple CPU in Xilinx Spartan 3E FPGA based Digilent Basys2 board

This simple CPU is running on Digilent Basys2 with basic instructions. It is Von Neumann architecture. Each instruction is 32 bit. ALU(Arithmetic Logic Unit) is capable of 32 bit if operands are loaded from memory. Otherwise direct operations only support 14 bit. GitHub (https://github.com/hasanunlu/simple_cpu) has all necessary files (Design files, binary download, memory dump and example bubble sort assembly file)

Screen Shot 2018-08-27 at 12.01.39 AM

Instruction Set of Simple CPU:

ADD -> unsigned Add
{opcode, i} = {0, 0}
*A <- (*A) + (*B)
write ( readFromAddress(A) + readAddress(B) ) to address ( A )
*A = value (content of) address A = mem[A] (mem means memory)
*B = value (content of) address B = mem[B]
<- means write (assign)
mem[A] = mem[A] + mem[B]
mem[IW[27:14]] = mem[IW[27:14]] + mem[IW[13:0]]

ADDi -> unsigned Add immediate
{opcode, i} = {0, 1}
*A <- (*A) + B
B = read section B of the Instruction
mem[A] = mem[A] + B
mem[IW[27:14]] = mem[IW[27:14]] + IW[13:0]

MUL -> unsigned Multiply
{opcode, i} = {7, 0}
*A <- (*A) * (*B)

MULi -> unsigned Multiply
{opcode, i} = {7, 1}
*A <- (*A) * B

NAND -> bitwise NAND
{opcode, i} = {1, 0}
*A <- ~((*A) & (*B))
{opcode, i} = {0, 1}

NANDi -> bitwise NAND immediate
{opcode, i} = {1, 1}
*A <- ~((*A) & B)

SRL -> Shift Right if the shift amount (*B) is less than 32, otherwise Shift Left
{opcode, i} = {2, 0}
*A (*B)) : ((*A) << ((*B) – 32))

SRLi -> Shift Right if the shift amount (B) is less than 32, otherwise Shift Left
{opcode, i} = {2, 0}
*A B) : ((*A) << (B – 32))

LT -> if *A is Less Than *B then *A is set to 1, otherwise to 0.
{opcode, i} = {3, 0}
*A <- ((*A) < (*B))

LTi -> if *A is Less Than B then *A is set to 1, otherwise to 0.
{opcode, i} = {3, 1}
*A <- ((*A) < B)

CP -> Copy *B to *A
{opcode, i} = {4, 0}
*A <- *B

CPi -> Copy B to *A
{opcode, i} = {4, 1}
*A <- B

CPI -> (regular) Copy Indirect: Copy **B to *A
(go to address B and fetch the number then treat it as an address and go to that address and get that data and write to address A)
{opcode, i} = {5, 0}
*A <- *(*B)
write ( readFromAddress(readFromAddress(B)) ) to address ( A )

CPIi -> (immediate) Copy Indirect: Copy *B to **A
(go to address B and fetch the number (*B) then go to address A and fetch the number there and treat it as an address and write there *B)
{opcode, i} = {5, 1}
*(*A) <- *B
write ( readFromAddress(B) ) to address ( readFromAddress(A) )

BZJ -> Branch on Zero
(Branch to *A if *B is Zero, otherwise increment Program Counter (PC))
{opcode, i} = {6, 0}
PC <- (*B == 0) ? (*A) : (PC+1)
if(*B == 0) goTo(*A), else goTo(nextInstruction)

BZJi -> Jump (unconditional branch)
{opcode, i} = {6, 1}
PC <- (*A) + B

Example bubble sort assembly code: bubble_sort.asm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s