Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSPT13-Karthik-CompArc #254

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions asm/call.asm
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

; Demonstrate calls
;
; Expected output:
Expand Down
2 changes: 1 addition & 1 deletion asm/mult.asm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# Expected output: 72

LDI R0,8
LDI R0,8
LDI R1,9
MUL R0,R1
PRN R0
Expand Down
15 changes: 15 additions & 0 deletions asm/test.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
; Code to test the Sprint Challenge
;
; Expected output:
; 1
; 4
; 5

LDI R0,10
LDI R1,20
LDI R2,Test1
CMP R0,R1
JEQ R2 ; Does not jump because R0 != R1
LDI R3,1
PRN R3 ; Prints 1
HLT
140 changes: 114 additions & 26 deletions ls8/cpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,61 @@

import sys

class CPU:
"""Main CPU class."""
HLT = 0b00000001
LDI = 0b10000010
PRN = 0b01000111
MUL = 0b10100010
PUSH = 0b01000101
POP = 0b01000110
CALL = 0b01010000
RET = 0b00010001
JMP = 0b01010100
CMP = 0b10100111
JEQ = 0b01010101
JNE = 0b01010110
SP = 7

class CPU:
def __init__(self):
"""Construct a new CPU."""
pass

def load(self):
"""Load a program into memory."""

address = 0
self.ram = [0] * 256
self.pc = 0
self.reg = [0] * 8
self.reg[7] = 0xF4 #refer PowerON state in Spec
self.running = True
self.fl = 0b00000000

# For now, we've just hardcoded a program:
def ram_read(self,addr):
return self.ram[addr]

program = [
# From print8.ls8
0b10000010, # LDI R0,8
0b00000000,
0b00001000,
0b01000111, # PRN R0
0b00000000,
0b00000001, # HLT
]
def ram_write(self,val,addr):
self.ram[addr] = val

for instruction in program:
self.ram[address] = instruction
address += 1
def load(self,filename):
"""Load a program into memory."""

address = 0
# program = []
try:
with open(filename) as f:
for line in f:
comment_split = line.split("#")
maybe_binary_number = comment_split[0].strip()
try:
x = int(maybe_binary_number, 2)
self.ram_write(x, address)
address += 1
except:
continue
except FileNotFoundError:
print("Cannot find this file..")

def alu(self, op, reg_a, reg_b):
"""ALU operations."""

if op == "ADD":
self.reg[reg_a] += self.reg[reg_b]
#elif op == "SUB": etc
# if op == "ADD":
# self.reg[reg_a] += self.reg[reg_b]
if op == MUL:
self.reg[reg_a] *= self.reg[reg_b]
else:
raise Exception("Unsupported ALU operation")

Expand All @@ -60,6 +80,74 @@ def trace(self):

print()


def num_of_operands(self, instruction_to_execute):
return ((instruction_to_execute >> 6) & 0b11) + 1

def run(self):
"""Run the CPU."""
pass

#self.load()
while self.running:
instruction_to_excecute = self.ram[self.pc]
operand_a = self.ram_read(self.pc+1)
operand_b = self.ram_read(self.pc+2)
if instruction_to_excecute == LDI:
self.reg[operand_a] = operand_b
self.pc += self.num_of_operands(instruction_to_excecute)
elif instruction_to_excecute == PRN:
reg = self.reg[operand_a]
print (reg)
self.pc += self.num_of_operands(instruction_to_excecute)
elif instruction_to_excecute == HLT:
self.running = False
self.pc += self.num_of_operands(instruction_to_excecute)
elif instruction_to_excecute == MUL:
self.alu(instruction_to_excecute,operand_a,operand_b)
self.pc += self.num_of_operands(instruction_to_excecute)
elif instruction_to_excecute == PUSH:
self.reg[SP] -=1 # decrement the stack pointer
self.ram_write(self.reg[operand_a],self.reg[SP])
self.pc += self.num_of_operands(instruction_to_excecute)
elif instruction_to_excecute == POP:
self.reg[operand_a] = self.ram_read(self.reg[SP])
self.reg[SP]+=1
self.pc += self.num_of_operands(instruction_to_excecute)
elif instruction_to_excecute == CALL:
self.reg[SP]-=1
addr_of_next_inst = self.pc+2
self.ram_write(addr_of_next_inst,self.reg[SP])
reg_to_get_addr_from = operand_a
jump_to_addr = self.reg[reg_to_get_addr_from]
self.pc = jump_to_addr
elif instruction_to_excecute == RET:
addr_to_return = self.ram_read(self.reg[SP])
self.pc = addr_to_return
self.reg[SP]+=1
elif instruction_to_excecute == JMP:
self.pc = self.reg[operand_a]
elif instruction_to_excecute == CMP:
if self.reg[operand_a]>self.reg[operand_b]:
self.fl = 0b00000010
elif self.reg[operand_a]<self.reg[operand_b]:
self.fl = 0b00000100
else:
self.fl = 0b00000001
self.pc += self.num_of_operands(instruction_to_excecute)
elif instruction_to_excecute == JNE:
if self.fl != 0b00000001:
self.pc = self.reg[operand_a]
else:
self.pc += self.num_of_operands(instruction_to_excecute)
elif instruction_to_excecute == JEQ:
if self.fl == 0b00000001:
self.pc = self.reg[operand_a]
else:
self.pc += self.num_of_operands(instruction_to_excecute)
else:
print ("idk what to to")
sys.exit()




112 changes: 112 additions & 0 deletions ls8/lecture.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import sys

# machine that excecutes an instruction

# op-code - represent the instruction that is supposed to be executed
PRINT_HI = 1
HALT = 2
PRINT_NUM = 3
SAVE = 4 # SAVE a val in reg
PRINT_REGISTER = 5
ADD = 6 #takes 2 reg A and B, adds both and stores in reg A
PUSH = 7 # takes in a register and stores a val in that reg on top of a stack
POP = 8 # takes in a register and stores topmost element in the stack in it.
CALL =9
RET = 10
PRINT_SUBROUTINE = 11

def load_memory():
program = [
PRINT_HI,
SAVE, # save val 65 in reg 2
7,
2,
CALL,
2,
HALT,
PRINT_SUBROUTINE,
SAVE,
500,
0,
RET
]
space_for_stack = 128 - len(program)
memory = program + [0] * space_for_stack
return memory

memory = load_memory()

registers = [0] * 8 #8 registers
stack_pointer_register = 7
registers[stack_pointer_register] = len(memory)-1 #address of stack pointer

program_counter = 0 # points to curr inst we need to execute next
running = True

#keep looping while not Halted

while running:
command_to_execute = memory[program_counter]

if command_to_execute == PRINT_HI:
print("hi")
program_counter+=1
elif command_to_execute == PRINT_NUM:
number_to_print = memory[program_counter +1]
print(f"{number_to_print}")
program_counter+=2
elif command_to_execute == SAVE:
value_to_save = memory[program_counter+1]
register_to_save_it_in = memory[program_counter+2]
registers[register_to_save_it_in] = value_to_save
program_counter+=3
elif command_to_execute == PRINT_REGISTER:
register_to_print = memory[program_counter+1]
print(f"{registers[register_to_print]}")
program_counter +=2
elif command_to_execute == ADD:
register_a = memory[program_counter+1]
register_b = memory[program_counter+2]
sum_of_reg = registers[register_a]+registers[register_b]
registers[register_a] = sum_of_reg
program_counter +=3
elif command_to_execute == HALT:
running = False
program_counter+=1
elif command_to_execute == PUSH:
registers[stack_pointer_register] -=1 # decrement stack pointer
register_to_get_value_in = memory[program_counter+1]
value_in_register = registers[register_to_get_value_in]
memory[registers[stack_pointer_register]] = value_in_register
program_counter +=2
elif command_to_execute == POP:
register_to_pop_value_in = memory[program_counter+1]
registers[register_to_pop_value_in] = memory[registers[stack_pointer_register]]
registers[stack_pointer_register]+=1
program_counter+=2
elif command_to_execute == PRINT_SUBROUTINE:
print('I am in a SubRoutine')
program_counter+=1
elif command_to_execute == CALL:
#Takes in a register and stores address of next instruction on top of stack
# it jumps to address stored in that register
registers[stack_pointer_register] -=1
address_of_next_inst = program_counter+2
memory[registers[stack_pointer_register]] = address_of_next_inst
register_to_get_addr_from = memory[program_counter+1]
program_counter = registers[register_to_get_addr_from]
elif command_to_execute == RET:
# pops top element of stack and sets PC to it
# does not take any operand
program_counter = memory[registers[stack_pointer_register]]
registers[stack_pointer_register]+=1
else:
print("unknown instruction {command_to_execute}")
sys.exit(1)

print (registers)
print (memory)




9 changes: 7 additions & 2 deletions ls8/ls8.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,10 @@

cpu = CPU()

cpu.load()
cpu.run()
filename = sys.argv[1]
cpu.load(filename)
cpu.run()