Commit dc5beff3 authored by Khoi Lam's avatar Khoi Lam 💬
Browse files

Lab 7, jal and jalr not working

parent eebb22cd
......@@ -7,20 +7,23 @@ def alu(op1, op2, alu_fun):
elif alu_fun == 2: #cp
return op1
elif alu_fun == 3: #sltu
return op1 << op2
if as_twos_comp(op1) < as_twos_comp(op2):
return 1
else:
return 0
elif alu_fun == 4: #and
return op1 & op2
elif alu_fun == 5: #add
return op1 + op2
return sextend(0xffffffff & (op1 + op2))
elif alu_fun == 6: #set less than
if op1 < op2: return 1
return 0
elif alu_fun == 7: #shift right arithmetic
return op1 >> op2
return op1 >> (0x1f & op2)
elif alu_fun == 8: #sub
return op1 - op2
return sextend(0xffffffff & (op1 - op2))
elif alu_fun == 9: #shift right logical
return sextend(as_twos_comp(op1) >> (0x1f & op2))
return sextend(0xffffffff & (as_twos_comp(op1) >> (0x1f & op2)))
elif alu_fun == 10: #shift left logical
return sextend(0xffffffff & (as_twos_comp(op1) << (0x1f & op2)))
elif alu_fun == 11: #Or
......
# filename: fetch_decode.py
import itertools
import sys
import os
from pydigital.memory import readmemh
from pydigital.memory import Memory
from pydigital.memory import MemorySegment
......@@ -14,26 +15,27 @@ from pydigital.elfloader import load_elf
from pydigital.utils import as_twos_comp
from pydigital.utils import sextend
# the PC register
PC = Register()
# run cpu
def run_cpu(imem, dmem, symbols, debug):
# the PC register
PC = Register()
# construct a memory segment for instruction memory
# load the contents from the 32-bit fetch_test hex file (big endian)
# imem = readmemh('riscv_isa/programs/fetch_test.hex',
# word_size = 4, byteorder = 'big')
pc_val = PC.out()
pc_val = PC.out()
def display(pc_val, instr):
if pc_val == None:
return "PC: xxxxxxxx, IR: xxxxxxxx"
else:
return f"PC: {pc_val:08x}, IR: {instr.val:08x}, {instr}" # {instr} just returns the representation of the instruction that we overloaded with __str__ in isa.py
# run cpu
def run_cpu(imem, dmem, symbols, debug):
def display(pc_val, instr):
if pc_val == None:
return "PC: xxxxxxxx, IR: xxxxxxxx"
else:
return f"PC: {pc_val:08x}, IR: {instr.val:08x}, {instr}" # {instr} just returns the representation of the instruction that we overloaded with __str__ in isa.py
startup = True
# create the regfile
......@@ -53,8 +55,8 @@ def run_cpu(imem, dmem, symbols, debug):
print(f"{t:20d}:", display(pc_val, instr))
continue
# print one line at the end of the clock cycle
print(f"{t:20d}:", display(pc_val, instr))
if debug != 0:
print(f"{t:20d}:", display(pc_val, instr))
# clock logic blocks, PC is the only clocked module!
# decide next PC based on what instruction is run
......@@ -105,12 +107,20 @@ def run_cpu(imem, dmem, symbols, debug):
print("Sextended_ALURes = " + str(sextend_res))
print("ALU_fun = " + str(alu_fun))
#print(instr.instr_name)
# Data Memory Read
if mem_wr == 0 and mem_em == 1:
rdata = dmem.out(as_twos_comp(result))
if instr.instr_name == "lb":
#print("DCM")
rdata = dmem.out(as_twos_comp(result), 1)
elif instr.instr_name == "lbu":
rdata = dmem.out(as_twos_comp(result), 1, False)
elif instr.instr_name == "lh":
rdata = dmem.out(as_twos_comp(result), 2)
elif instr.instr_name == "lhu":
rdata = dmem.out(as_twos_comp(result), 2, False)
# Data Memory Write
dmem.clock(as_twos_comp(result), rs2_value, mem_wr, mem_val)
......@@ -122,8 +132,10 @@ def run_cpu(imem, dmem, symbols, debug):
my_reg.clock(int(instr.rd,2), writeback_mux(wb_sel), rf_wen)
if instr.instr_name == "jal":
print(instr.immUJ)
PC.clock(instr.immUJ + pc_val)
elif instr.instr_name == "jalr":
print(rs1_value)
PC.clock(instr.immI + rs1_value)
elif isTaken:
PC.clock(instr.immSB + pc_val)
......@@ -131,7 +143,8 @@ def run_cpu(imem, dmem, symbols, debug):
PC.clock(pc_val + 4)
rd_value = my_reg.read(int(instr.rd, 2))
print(' rd_val: ' + str(rd_value) + ' rs1_val: ' + format(rs1_value, "x") + ' rs2_val: ' + format(rs2_value, "x") )
if debug != 0:
print(' rd_val: ' + str(rd_value) + ' rs1_val: ' + format(rs1_value, "x") + ' rs2_val: ' + format(rs2_value, "x") )
if pc_val in symbols:
print ("-"*10 + symbols[pc_val] + "-"*10)
......@@ -145,12 +158,17 @@ def run_cpu(imem, dmem, symbols, debug):
# the default values for instr are strings, if you want them as ints you will need to do int(,2)
if instr.instr_name == "ecall":
if ecall_val == 0:
print('ECALL(' + str(format(ecall_val)) + '): ' + 'HALT')
elif ecall_val == 10:
print('ECALL(' +str(format(ecall_val)) +'): ' + 'EXIT')
if my_reg.read(17) == 93:
return ecall_val
else:
print('ECALL(' +str(format(ecall_val)) +'): ' + str(my_reg.read(11)))
if ecall_val == 0:
print('ECALL(' + str(format(ecall_val)) + '): ' + 'HALT')
elif ecall_val == 10:
print('ECALL(' +str(format(ecall_val)) +'): ' + 'EXIT')
else:
print('ECALL(' +str(format(ecall_val)) +'): ' + str(my_reg.read(11)))
if mem_em == 1 and mem_wr == 1 and 'tohost' in symbols:
if (word_size == 4 and result == symbols['tohost']+4) or (word_size == 8 and result == symbols['tohost']):
......@@ -186,15 +204,36 @@ def run_cpu(imem, dmem, symbols, debug):
if __name__ == "__main__":
if len(sys.argv) == 1:
program_file = "riscv_isa/programs/return" # default instruction file
else:
program_file = sys.argv[1] # or choose another file
# construct a memory segment for the instruction memory
# load the contents from the 32-bit fetch_test hex file (big endian)
sys_mem, symbols = load_elf(program_file)
imem = sys_mem
dmem = Memory(sys_mem) #for lab 5
sys.exit(run_cpu(imem, dmem, symbols, debug = 0))
# if len(sys.argv) == 1:
# program_file = "riscv_isa/programs/return" # default instruction file
# else:
# program_file = sys.argv[1] # or choose another file
# # construct a memory segment for the instruction memory
# # load the contents from the 32-bit fetch_test hex file (big endian)
# sys_mem, symbols = load_elf(program_file)
# imem = sys_mem
# dmem = Memory(sys_mem) #for lab 5
# if (run_cpu(imem, dmem, symbols, debug = 0)) == 0:
# print("TEST PASS")
# else:
# print("TEST FAIL")
directory = "riscv_isa/programs/riscv-test/"
for filename in os.listdir(directory):
print(filename)
program_file = directory + filename
sys_mem, symbols = load_elf(program_file)
imem = sys_mem
dmem = Memory(sys_mem)
is_passed = run_cpu(imem, dmem, symbols, debug = 0);
if is_passed == 0:
test_result = "TEST PASS"
else:
test_result = "TEST_FAIL"
print(directory + filename + ': ' + test_result)
\ No newline at end of file
......@@ -35,7 +35,9 @@ i_type = {
"110": "ori",
"001": "slli",
"111": "andi",
"101": "srai"
"101": "srai",
"100": "xori",
"011": "sltiu"
}
}
......@@ -50,6 +52,9 @@ i_type_2 = {
"NA": {
"010": "lw",
"100": "lbu",
"000": "lb",
"001": "lh",
"101": "lhu"
}
}
......@@ -191,6 +196,7 @@ class Instruction():
self.opcode = self.bin_val[25:] # 7 bits
self.immU = sextend((val & 0xFFFFF000), 32)
self.immI = sextend((val & 0xFFF00000) >> 20, 12)
self.bullshit = (0xFE0 & self.immI)
self.immS = sextend(0xfff & ((0x1f & (val >> 7)) | ((0x7f & (val >> 25)) << 5)), 12)
self.immSB = sextend(
0x1fffff & (
......@@ -215,6 +221,9 @@ class Instruction():
elif self.type == "i":
if self.opcode != "0000011":
self.instr_name = i_type["NA"][self.func3]
if self.instr_name == "srai":
if self.bullshit == 0:
self.instr_name = "srli"
elif self.type == "i1":
self.instr_name = i_type_1["NA"][self.func3]
elif self.type == "i2":
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment