Update gitignore, clean code
This commit is contained in:
parent
b0b7c993d4
commit
75d0268477
7 changed files with 37 additions and 42 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,2 +1,4 @@
|
||||||
# Do not include python cache
|
# Do not include python cache
|
||||||
__pycache__
|
__pycache__
|
||||||
|
.pydevproject
|
||||||
|
.project
|
||||||
|
|
|
@ -6,22 +6,20 @@ class Caretaker:
|
||||||
|
|
||||||
def __init__(self,ramSize):
|
def __init__(self,ramSize):
|
||||||
self.objects=dict() # Create empty objects pool
|
self.objects=dict() # Create empty objects pool
|
||||||
# Add registers to pool
|
## Add registers to pool ##
|
||||||
for reg in ["MAR","MDR", "PC", "MBR", "SP","LV","CPP","TOS","OPC","H"]:
|
for reg in ["MAR","MDR", "PC", "MBR", "SP","LV","CPP","TOS","OPC","H"]:
|
||||||
self.objects[reg]=0
|
self.objects[reg]=0
|
||||||
self.objects["RAM"]=Ram(self,ramSize)
|
self.objects["RAM"]=Ram(self,ramSize) # Create ram
|
||||||
|
|
||||||
def __getitem__(self,key):
|
def __getitem__(self,key):
|
||||||
if key=="MBRU": # If we ask for unsigned
|
if key=="MBRU": # If we ask for unsigned
|
||||||
return(abs(self.objects["MBR"]))
|
return(abs(self.objects["MBR"]))
|
||||||
elif key== "MBR":
|
elif key== "MBR": # If we ask for signed
|
||||||
if self.objects[key] < 0:
|
if self.objects[key] < 0: # If its already signed
|
||||||
return(self.objects[key])
|
return(self.objects[key])
|
||||||
elif self.objects[key]>>7==1: # If it a negative number (2 complement)
|
elif self.objects[key]>>7==1: # Otherwise compute its python version
|
||||||
#return(-(self.objects[key]&0x7F))
|
return(-((self.objects[key]-1)^0xFF)) # Reverse 2 complements to get an unsigned number then negate it
|
||||||
return(-((self.objects[key]-1)^0xFF)) # Reverse 2 complements to get an unsign nummber (for python is better)
|
else: # Otherwise it is positive
|
||||||
|
|
||||||
else:
|
|
||||||
return(self.objects[key])
|
return(self.objects[key])
|
||||||
return(self.objects[key])
|
return(self.objects[key])
|
||||||
|
|
||||||
|
|
|
@ -26,5 +26,5 @@ ijvm=dict({
|
||||||
})
|
})
|
||||||
|
|
||||||
# Add extras instructions
|
# Add extras instructions
|
||||||
ijvm["OUT"]=0x23 # Print next byte as char
|
ijvm["OUT"]=0x23 # Print next byte as char
|
||||||
ijvm["HALT"]=0x2F # Stop simulator
|
ijvm["HALT"]=0x2F # Halt simulator
|
||||||
|
|
|
@ -12,31 +12,31 @@ class Microprogram:
|
||||||
"""
|
"""
|
||||||
Start microprogram
|
Start microprogram
|
||||||
"""
|
"""
|
||||||
self.c["LV"]=stackLocation# Place stack to 1024
|
self.c["LV"]=stackLocation # Init stack location
|
||||||
self.c["SP"]=stackLocation-1 # Init SP to LV-1 (because otherwise first element of the stack will be enty because of BIPUSH impl
|
self.c["SP"]=stackLocation-1 # Init SP to LV-1 otherwise first element of the stack will be empty (because of BIPUSH implementation)
|
||||||
self.c["CPP"]=constantPoolLocation
|
self.c["CPP"]=constantPoolLocation # Init constant pool location
|
||||||
|
|
||||||
for i in range(1,30): # Launche first 30 insctructions
|
for i in range(1,100): # Launch 100 first instructions (Find another solution)
|
||||||
self.fetch() # Fetch
|
self.fetch() # Fetch
|
||||||
self.c["PC"]+=1 # INC PC after fetch
|
self.c["PC"]+=1 # INC PC after fetch
|
||||||
if self.exec()==1: # Execute opcode and halt if return code is 1
|
if self.exec()==1: # Execute opcode and halt if return code is 1
|
||||||
break;
|
break;
|
||||||
|
|
||||||
def fetch(self):
|
def fetch(self): # "Structured Computer Organization" implementation
|
||||||
"""
|
"""
|
||||||
Fetch next byte from memory into MBR
|
Fetch next byte from memory into MBR
|
||||||
"""
|
"""
|
||||||
opcode=self.c["RAM"].fetch()
|
opcode=self.c["RAM"].fetch()
|
||||||
self.c["MBR"]=opcode # Opcode to MBR
|
self.c["MBR"]=opcode # Opcode to MBR
|
||||||
|
|
||||||
def rd(self):
|
def rd(self): # "Structured Computer Organization" implementation
|
||||||
"""
|
"""
|
||||||
Read data into memory
|
Read data into memory
|
||||||
"""
|
"""
|
||||||
self.c["MAR"]=self.c["MAR"]*4 # Don't forget MAR address 32bits block of memory
|
self.c["MAR"]=self.c["MAR"]*4 # Don't forget MAR address 32bits block of memory
|
||||||
little_endian=self.c["RAM"].read()
|
little_endian=self.c["RAM"].read()
|
||||||
self.c["MAR"]=self.c["MAR"]/4 # Restore MAR
|
self.c["MAR"]=self.c["MAR"]/4 # Restore MAR
|
||||||
##### Build little endian version of MDR ####
|
##### Restore bit order into big endian ####
|
||||||
big_endian=(little_endian&0xFF)<<24
|
big_endian=(little_endian&0xFF)<<24
|
||||||
big_endian=big_endian|(((little_endian>>8)&0xFF)<<16)
|
big_endian=big_endian|(((little_endian>>8)&0xFF)<<16)
|
||||||
big_endian=big_endian|(((little_endian>>16)&0xFF)<<8)
|
big_endian=big_endian|(((little_endian>>16)&0xFF)<<8)
|
||||||
|
@ -44,7 +44,7 @@ class Microprogram:
|
||||||
##############################################
|
##############################################
|
||||||
self.c["MDR"]=big_endian
|
self.c["MDR"]=big_endian
|
||||||
|
|
||||||
def wr(self):
|
def wr(self): # "Structured Computer Organization" implementation
|
||||||
"""
|
"""
|
||||||
Write data into memory
|
Write data into memory
|
||||||
"""
|
"""
|
||||||
|
@ -61,7 +61,7 @@ class Microprogram:
|
||||||
self.c["MAR"]=self.c["MAR"]/4 # Restore MAR
|
self.c["MAR"]=self.c["MAR"]/4 # Restore MAR
|
||||||
self.c["MDR"]=big_endian # Restore big endian
|
self.c["MDR"]=big_endian # Restore big endian
|
||||||
|
|
||||||
def exec(self): # TODO: Implement opcode
|
def exec(self): # TODO: Implement some other opcodes
|
||||||
"""
|
"""
|
||||||
Execute next opcode
|
Execute next opcode
|
||||||
"""
|
"""
|
||||||
|
@ -147,11 +147,11 @@ class Microprogram:
|
||||||
self.rd()
|
self.rd()
|
||||||
self.c["TOS"]=self.c["MDR"]
|
self.c["TOS"]=self.c["MDR"]
|
||||||
elif opcode==ijvm["IINC"]:
|
elif opcode==ijvm["IINC"]:
|
||||||
self.fetch();self.c["PC"]+=1 # Fetch local variable offset to inc
|
self.fetch();self.c["PC"]+=1 # Fetch local variable offset to increment
|
||||||
self.c["H"]=self.c["LV"]
|
self.c["H"]=self.c["LV"]
|
||||||
self.c["MAR"]=self.c["MBRU"]+self.c["H"]
|
self.c["MAR"]=self.c["MBRU"]+self.c["H"]
|
||||||
self.rd()
|
self.rd()
|
||||||
self.fetch();self.c["PC"]+=1 # Fetch inc value
|
self.fetch();self.c["PC"]+=1 # Fetch increment value
|
||||||
self.c["H"]=self.c["MDR"]
|
self.c["H"]=self.c["MDR"]
|
||||||
self.c["MDR"]=self.c["MBR"]+self.c["H"]
|
self.c["MDR"]=self.c["MBR"]+self.c["H"]
|
||||||
self.wr()
|
self.wr()
|
||||||
|
@ -164,7 +164,7 @@ class Microprogram:
|
||||||
self.c["PC"]=self.c["OPC"]+self.c["H"]
|
self.c["PC"]=self.c["OPC"]+self.c["H"]
|
||||||
elif opcode==ijvm["OUT"]:
|
elif opcode==ijvm["OUT"]:
|
||||||
self.fetch();self.c["PC"]+=1 # Fetch byte to push in MBR
|
self.fetch();self.c["PC"]+=1 # Fetch byte to push in MBR
|
||||||
print(str(chr(self.c["MBRU"])),end="") # MBRU because no char which are negative
|
print(str(chr(self.c["MBRU"])),end="") # MBRU because there is no negative char
|
||||||
elif opcode==ijvm["IFEQ"]:
|
elif opcode==ijvm["IFEQ"]:
|
||||||
self.c["SP"]=self.c["SP"]-1
|
self.c["SP"]=self.c["SP"]-1
|
||||||
self.c["MAR"]=self.c["SP"]
|
self.c["MAR"]=self.c["SP"]
|
||||||
|
@ -194,7 +194,7 @@ class Microprogram:
|
||||||
raise RuntimeError("Instruction {} not found on address {}".format(opcode,self.c["PC"]-1))
|
raise RuntimeError("Instruction {} not found on address {}".format(opcode,self.c["PC"]-1))
|
||||||
return(0)
|
return(0)
|
||||||
|
|
||||||
def T(self): # This function is here just to follow ijvm implementation of "Structured Computer Organization"
|
def T(self): # "Structured Computer Organization" implementation
|
||||||
self.fetch();self.c["PC"]+=1 # exactly like GOTO implementation
|
self.fetch();self.c["PC"]+=1 # exactly like GOTO implementation
|
||||||
self.c["OPC"]=self.c["PC"]-1 # exactly like GOTO implementation
|
self.c["OPC"]=self.c["PC"]-1 # exactly like GOTO implementation
|
||||||
###### GOTO2 #####
|
###### GOTO2 #####
|
||||||
|
@ -204,7 +204,7 @@ class Microprogram:
|
||||||
self.c["PC"]=self.c["OPC"]+self.c["H"]
|
self.c["PC"]=self.c["OPC"]+self.c["H"]
|
||||||
##################
|
##################
|
||||||
|
|
||||||
def F(self): # This function is here just to follow ijvm implementation of "Structured Computer Organization"
|
def F(self): # "Structured Computer Organization" implementation
|
||||||
self.fetch();self.c["PC"]+=1 # Needed because memory access take 1 cycle in simulation
|
self.fetch();self.c["PC"]+=1 # Needed because memory access take 1 cycle in simulation
|
||||||
self.c["PC"]=self.c["PC"]+1
|
self.c["PC"]=self.c["PC"]+1
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,9 @@ def dump(ram,title): # Simple Helper function
|
||||||
c=Caretaker(5000) # Init components ram size in byte
|
c=Caretaker(5000) # Init components ram size in byte
|
||||||
c["RAM"].loadRamFile("./ram.txt") # Load Ram from file
|
c["RAM"].loadRamFile("./ram.txt") # Load Ram from file
|
||||||
|
|
||||||
mic=Microprogram(c) # Create micro program
|
mic=Microprogram(c) # Create microprogram
|
||||||
dump(c["RAM"], "Ram Before Execution") # Dump ram before execution
|
dump(c["RAM"], "Ram Before Execution") # Dump ram before execution
|
||||||
mic.run(800, 1024) # Run the micro program with run(constantPoolLocation,stackLocation)
|
mic.run(800, 1024) # Run the microprogram with run(constantPoolLocation,stackLocation)
|
||||||
dump(c["RAM"],"Ram After Execution") # Dump ram after execution
|
dump(c["RAM"],"Ram After Execution") # Dump ram after execution
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,12 @@ class CaretakerTest(unittest.TestCase):
|
||||||
"""
|
"""
|
||||||
Test if getitem operation follow Mic-1 rules
|
Test if getitem operation follow Mic-1 rules
|
||||||
"""
|
"""
|
||||||
for toWrite in range(0,127):# Only 7 bit for signed MBR (2^7=127)
|
for toWrite in range(0,127): # Only 7 bit for signed MBR (2^7=127)
|
||||||
self.c["MBR"]=-toWrite
|
self.c["MBR"]=-toWrite
|
||||||
self.assertEqual(self.c["MBRU"],toWrite,"Tested with {}".format(-toWrite))
|
self.assertEqual(self.c["MBRU"],toWrite,"Tested with {}".format(-toWrite))
|
||||||
self.assertEqual(self.c["MBR"],-toWrite,"Tested with {}".format(-toWrite))
|
self.assertEqual(self.c["MBR"],-toWrite,"Tested with {}".format(-toWrite))
|
||||||
|
|
||||||
for toWrite in range(0,255):# Only 2^8 value for unsigned
|
for toWrite in range(0,255): # Only 2^8 value for unsigned
|
||||||
self.c["MBR"]=toWrite
|
self.c["MBR"]=toWrite
|
||||||
self.assertEqual(self.c["MBRU"],toWrite,"Tested with {}".format(toWrite))
|
self.assertEqual(self.c["MBRU"],toWrite,"Tested with {}".format(toWrite))
|
||||||
if toWrite>127: # We enter in the zone of negative number at 127
|
if toWrite>127: # We enter in the zone of negative number at 127
|
||||||
|
@ -40,7 +40,7 @@ class CaretakerTest(unittest.TestCase):
|
||||||
with self.assertRaises(Exception):
|
with self.assertRaises(Exception):
|
||||||
self.c["PC"]=-(2**31)
|
self.c["PC"]=-(2**31)
|
||||||
|
|
||||||
def test___setitem__(self):
|
def test___setitem__(self): # TODO: improve tests
|
||||||
"""
|
"""
|
||||||
Test if getitem operation follow Mic-1 rules
|
Test if getitem operation follow Mic-1 rules
|
||||||
"""
|
"""
|
||||||
|
@ -50,9 +50,5 @@ class CaretakerTest(unittest.TestCase):
|
||||||
self.fail("Failed to assign RAM to caretaker")
|
self.fail("Failed to assign RAM to caretaker")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -11,7 +11,7 @@ class RamTest(unittest.TestCase):
|
||||||
Init test
|
Init test
|
||||||
"""
|
"""
|
||||||
self.caretaker=dict({"MDR":0,"MAR":0,"MBR":0,"PC":0})
|
self.caretaker=dict({"MDR":0,"MAR":0,"MBR":0,"PC":0})
|
||||||
self.ramSize=1000*4 # Ram size should be a multiple of 4 to guaranty test validity
|
self.ramSize=1000*4 # I suppose ram size should be a multiple of 4 to guaranty test validity
|
||||||
|
|
||||||
def test_write(self):
|
def test_write(self):
|
||||||
"""
|
"""
|
||||||
|
@ -22,16 +22,15 @@ class RamTest(unittest.TestCase):
|
||||||
toWrite=randint(0,2**i) # Pick a random number to write
|
toWrite=randint(0,2**i) # Pick a random number to write
|
||||||
self.caretaker["MDR"]=toWrite
|
self.caretaker["MDR"]=toWrite
|
||||||
self.caretaker["MAR"]=randint(0,self.ramSize-1)
|
self.caretaker["MAR"]=randint(0,self.ramSize-1)
|
||||||
|
|
||||||
ram=Ram(self.caretaker,self.ramSize)
|
ram=Ram(self.caretaker,self.ramSize)
|
||||||
ram.write() # Write a random number at address 0
|
ram.write() # Write a random number at address 0
|
||||||
|
|
||||||
data=ram.getData() # Dump ram
|
data=ram.getData() # Dump ram
|
||||||
##### Test if everything is written using big endian model #####
|
##### Test if everything is written using big endian model #####
|
||||||
self.assertEqual((toWrite>>24)&0xFF,data[self.caretaker["MAR"]])
|
self.assertEqual((toWrite>>24)&0xFF,data[self.caretaker["MAR"]])
|
||||||
self.assertEqual((toWrite>>16)&0xFF,data[self.caretaker["MAR"]+1])
|
self.assertEqual((toWrite>>16)&0xFF,data[self.caretaker["MAR"]+1])
|
||||||
self.assertEqual((toWrite>>8)&0xFF,data[self.caretaker["MAR"]+2])
|
self.assertEqual((toWrite>>8)&0xFF,data[self.caretaker["MAR"]+2])
|
||||||
self.assertEqual(toWrite&0xFF,data[self.caretaker["MAR"]+3])
|
self.assertEqual(toWrite&0xFF,data[self.caretaker["MAR"]+3])
|
||||||
|
|
||||||
# Test error is raise when writing out of memory
|
# Test error is raise when writing out of memory
|
||||||
self.caretaker["MDR"]=randint(0,2**i)
|
self.caretaker["MDR"]=randint(0,2**i)
|
||||||
self.caretaker["MAR"]=1000 # Write out of memory (positive address)
|
self.caretaker["MAR"]=1000 # Write out of memory (positive address)
|
||||||
|
@ -79,11 +78,11 @@ class RamTest(unittest.TestCase):
|
||||||
"""
|
"""
|
||||||
Test fetch method
|
Test fetch method
|
||||||
"""
|
"""
|
||||||
for q in range(0,1999):
|
for q in range(0,1999): # For fun
|
||||||
# Test classical fetch
|
# Test classical fetch
|
||||||
ram=Ram(self.caretaker,self.ramSize)
|
ram=Ram(self.caretaker,self.ramSize)
|
||||||
data=dict()
|
|
||||||
toWrite=randint(0,256-1)
|
toWrite=randint(0,256-1)
|
||||||
|
data=dict()
|
||||||
for i in range(0,self.ramSize):
|
for i in range(0,self.ramSize):
|
||||||
data[i]=toWrite
|
data[i]=toWrite
|
||||||
ram.setData(data)
|
ram.setData(data)
|
||||||
|
|
Loading…
Add table
Reference in a new issue