diff --git a/.gitignore b/.gitignore index 9337ccb..1982360 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ # Do not include python cache __pycache__ +.pydevproject +.project diff --git a/MicSim/components/caretaker.py b/MicSim/components/caretaker.py index cd6d913..e46c402 100644 --- a/MicSim/components/caretaker.py +++ b/MicSim/components/caretaker.py @@ -6,22 +6,20 @@ class Caretaker: def __init__(self,ramSize): 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"]: self.objects[reg]=0 - self.objects["RAM"]=Ram(self,ramSize) + self.objects["RAM"]=Ram(self,ramSize) # Create ram def __getitem__(self,key): if key=="MBRU": # If we ask for unsigned return(abs(self.objects["MBR"])) - elif key== "MBR": - if self.objects[key] < 0: + elif key== "MBR": # If we ask for signed + if self.objects[key] < 0: # If its already signed return(self.objects[key]) - elif self.objects[key]>>7==1: # If it a negative number (2 complement) - #return(-(self.objects[key]&0x7F)) - return(-((self.objects[key]-1)^0xFF)) # Reverse 2 complements to get an unsign nummber (for python is better) - - else: + elif self.objects[key]>>7==1: # Otherwise compute its python version + return(-((self.objects[key]-1)^0xFF)) # Reverse 2 complements to get an unsigned number then negate it + else: # Otherwise it is positive return(self.objects[key]) return(self.objects[key]) diff --git a/MicSim/components/ijvm.py b/MicSim/components/ijvm.py index 86f5f63..edcac60 100644 --- a/MicSim/components/ijvm.py +++ b/MicSim/components/ijvm.py @@ -26,5 +26,5 @@ ijvm=dict({ }) # Add extras instructions -ijvm["OUT"]=0x23 # Print next byte as char -ijvm["HALT"]=0x2F # Stop simulator +ijvm["OUT"]=0x23 # Print next byte as char +ijvm["HALT"]=0x2F # Halt simulator diff --git a/MicSim/components/microprogram.py b/MicSim/components/microprogram.py index 12f38e4..eafba61 100644 --- a/MicSim/components/microprogram.py +++ b/MicSim/components/microprogram.py @@ -12,31 +12,31 @@ class Microprogram: """ Start microprogram """ - self.c["LV"]=stackLocation# Place stack to 1024 - 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["CPP"]=constantPoolLocation + self.c["LV"]=stackLocation # Init stack location + 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 # Init constant pool location - for i in range(1,30): # Launche first 30 insctructions - self.fetch() # Fetch - self.c["PC"]+=1 # INC PC after fetch - if self.exec()==1: # Execute opcode and halt if return code is 1 + for i in range(1,100): # Launch 100 first instructions (Find another solution) + self.fetch() # Fetch + self.c["PC"]+=1 # INC PC after fetch + if self.exec()==1: # Execute opcode and halt if return code is 1 break; - def fetch(self): + def fetch(self): # "Structured Computer Organization" implementation """ Fetch next byte from memory into MBR """ opcode=self.c["RAM"].fetch() self.c["MBR"]=opcode # Opcode to MBR - def rd(self): + def rd(self): # "Structured Computer Organization" implementation """ Read data into memory """ self.c["MAR"]=self.c["MAR"]*4 # Don't forget MAR address 32bits block of memory little_endian=self.c["RAM"].read() 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=big_endian|(((little_endian>>8)&0xFF)<<16) big_endian=big_endian|(((little_endian>>16)&0xFF)<<8) @@ -44,7 +44,7 @@ class Microprogram: ############################################## self.c["MDR"]=big_endian - def wr(self): + def wr(self): # "Structured Computer Organization" implementation """ Write data into memory """ @@ -61,7 +61,7 @@ class Microprogram: self.c["MAR"]=self.c["MAR"]/4 # Restore MAR 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 """ @@ -147,11 +147,11 @@ class Microprogram: self.rd() self.c["TOS"]=self.c["MDR"] 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["MAR"]=self.c["MBRU"]+self.c["H"] 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["MDR"]=self.c["MBR"]+self.c["H"] self.wr() @@ -164,7 +164,7 @@ class Microprogram: self.c["PC"]=self.c["OPC"]+self.c["H"] elif opcode==ijvm["OUT"]: 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"]: self.c["SP"]=self.c["SP"]-1 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)) 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.c["OPC"]=self.c["PC"]-1 # exactly like GOTO implementation ###### GOTO2 ##### @@ -204,7 +204,7 @@ class Microprogram: 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.c["PC"]=self.c["PC"]+1 diff --git a/MicSim/micsim.py b/MicSim/micsim.py index 23a91fe..5ffa431 100755 --- a/MicSim/micsim.py +++ b/MicSim/micsim.py @@ -15,9 +15,9 @@ def dump(ram,title): # Simple Helper function c=Caretaker(5000) # Init components ram size in byte 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 -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 diff --git a/MicSim/test/test_caretaker.py b/MicSim/test/test_caretaker.py index cc8d2ef..d256a29 100644 --- a/MicSim/test/test_caretaker.py +++ b/MicSim/test/test_caretaker.py @@ -16,12 +16,12 @@ class CaretakerTest(unittest.TestCase): """ 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.assertEqual(self.c["MBRU"],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.assertEqual(self.c["MBRU"],toWrite,"Tested with {}".format(toWrite)) 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): self.c["PC"]=-(2**31) - def test___setitem__(self): + def test___setitem__(self): # TODO: improve tests """ Test if getitem operation follow Mic-1 rules """ @@ -50,9 +50,5 @@ class CaretakerTest(unittest.TestCase): self.fail("Failed to assign RAM to caretaker") - - - - if __name__ == "__main__": unittest.main() diff --git a/MicSim/test/test_ram.py b/MicSim/test/test_ram.py index f755753..a631180 100644 --- a/MicSim/test/test_ram.py +++ b/MicSim/test/test_ram.py @@ -11,7 +11,7 @@ class RamTest(unittest.TestCase): Init test """ 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): """ @@ -22,16 +22,15 @@ class RamTest(unittest.TestCase): toWrite=randint(0,2**i) # Pick a random number to write self.caretaker["MDR"]=toWrite self.caretaker["MAR"]=randint(0,self.ramSize-1) - ram=Ram(self.caretaker,self.ramSize) ram.write() # Write a random number at address 0 - data=ram.getData() # Dump ram ##### Test if everything is written using big endian model ##### self.assertEqual((toWrite>>24)&0xFF,data[self.caretaker["MAR"]]) self.assertEqual((toWrite>>16)&0xFF,data[self.caretaker["MAR"]+1]) self.assertEqual((toWrite>>8)&0xFF,data[self.caretaker["MAR"]+2]) self.assertEqual(toWrite&0xFF,data[self.caretaker["MAR"]+3]) + # Test error is raise when writing out of memory self.caretaker["MDR"]=randint(0,2**i) self.caretaker["MAR"]=1000 # Write out of memory (positive address) @@ -79,11 +78,11 @@ class RamTest(unittest.TestCase): """ Test fetch method """ - for q in range(0,1999): + for q in range(0,1999): # For fun # Test classical fetch ram=Ram(self.caretaker,self.ramSize) - data=dict() toWrite=randint(0,256-1) + data=dict() for i in range(0,self.ramSize): data[i]=toWrite ram.setData(data)