diff --git a/components/__init__.py b/components/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/components/caretaker.py b/components/caretaker.py new file mode 100644 index 0000000..ca15edd --- /dev/null +++ b/components/caretaker.py @@ -0,0 +1,20 @@ +#!/usr/bin/python + +class Caretaker: + + def __init__(self): + self.objects=dict() # Create empty objects 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"]=None + + def __getitem__(self,key): + return(self.objects[key]) + + def __setitem__(self,key,value):# TODO: Do special treatment for MBR + self.objects[key]=value + + def items(self): + return(self.objects.items()) + diff --git a/components/ijvm.py b/components/ijvm.py new file mode 100644 index 0000000..b8ca8a2 --- /dev/null +++ b/components/ijvm.py @@ -0,0 +1,24 @@ + +# Build IJVM +ijvm=dict({ + "BIPUSH":0x10, + "DUP":0x59, + "GOTO":0xA7, + "IADD":0x60, + "IAND":0x7E, + "IFEQ":0x99, + "IFLT":0x9B, + "IF_ICMPEQ":0x9F, + "IINC":0x84, + "ILOAD":0x15, + "INVOKEVIRTUAL":0xB6, + "IOR":0x80, + "IRETURN":0xAC, + "ISTORE":0x36, + "ISUB":0x64, + "LDC_W":0x13, + "NOP":0x00, + "POP":0x57, + "SWAP":0x5F, + "WIDE":0xC4 +}) diff --git a/components/microprogram.py b/components/microprogram.py new file mode 100644 index 0000000..f415fcf --- /dev/null +++ b/components/microprogram.py @@ -0,0 +1,103 @@ + +from components.ijvm import ijvm + +class Microprogram: + + def __init__(self,components): + self.c=components + if self.c["RAM"]==None: + raise RuntimeError("Microprogram initialization fail, RAM is not initialized") + + def run(self): + self.c["LV"]=(1024)# Place stack to 1024 + self.c["SP"]=(1024-1) # Init SP to LV-1 (because otherwise first element of the stack will be enty because of BIPUSH impl + + for i in range(1,30): # Launche first 30 insctructions + self.fetch() # Fetch + self.c["PC"]+=1 # INC PC + self.exec() # Execute opcode + + def fetch(self): + opcode=self.c["RAM"].fetch() + self.c["MBR"]=opcode # Opcode to MBR + + def rd(self): + data=self.c["RAM"].read() + self.c["MDR"]=data + + def wr(self): + self.c["RAM"].write() + + def exec(self):# link: https://users-cs.au.dk/bouvin/dComArk/2015/noter/Note_2/#Instructions + opcode=self.c["MBR"] # Get loaded OpCode + if opcode==ijvm["NOP"]: # NOP + pass + elif opcode==ijvm["BIPUSH"]: # BIPUSH + self.fetch();self.c["PC"]+=1 # Fetch byte to push in MBR + self.c["SP"]+=1 # Increment stack pointer + self.c["MAR"]=self.c["SP"] # Copy SP to MAR + self.c["MDR"]=self.c["MBR"] # Set MDR to MBR + self.c["TOS"]=self.c["MBR"] # Set MDR to MBR + self.wr() # Write data to stack + elif opcode==ijvm["IADD"]: + self.c["SP"]-=1 + self.c["MAR"]=self.c["SP"] + self.c["H"]=self.c["TOS"] + self.rd() + self.c["TOS"]=self.c["MDR"]+self.c["H"] + self.c["MDR"]=self.c["TOS"] + self.wr() + elif opcode==ijvm["ISUB"]: + self.c["SP"]-=1 + self.c["MAR"]=self.c["SP"] + self.c["H"]=self.c["TOS"] + self.rd() + self.c["TOS"]=self.c["MDR"]-self.c["H"] + self.c["MDR"]=self.c["TOS"] + self.wr() + elif opcode==ijvm["POP"]: + self.c["SP"]-=1 + self.c["MAR"]=self.c["SP"] + self.rd() + self.c["TOS"]=self.c["MDR"] + elif opcode==ijvm["DUP"]: + self.c["SP"]+=1 + self.c["MAR"]=self.c["SP"] + self.c["MDR"]=self.c["TOS"] + self.wr() + elif opcode==ijvm["IAND"]: + self.c["SP"]-=1 + self.c["MAR"]=self.c["SP"] + self.c["H"]=self.c["TOS"] + self.rd() + self.c["TOS"]=(self.c["MDR"] and self.c["H"]) + self.c["MDR"]=self.c["TOS"] + self.wr() + elif opcode==ijvm["IOR"]: + self.c["SP"]-=1 + self.c["MAR"]=self.c["SP"] + self.c["H"]=self.c["TOS"] + self.rd() + self.c["TOS"]=(self.c["MDR"] or self.c["H"]) + self.c["MDR"]=self.c["TOS"] + self.wr() + elif opcode==ijvm["SWAP"]: + self.c["MAR"]=self.c["SP"]-1 + self.rd() + self.c["MAR"]=self.c["SP"] + self.c["H"]=self.c["MDR"] + self.wr() + self.c["MDR"]=self.c["TOS"] + self.c["MAR"]=self.c["SP"]-1 + self.wr() + self.c["TOS"]=self.c["H"] + else: + if opcode in ijvm: + print("Instruction {} not yet implemented.".format(ijvm[opcode])) + else: + raise RuntimeError("Instruction {} not found".format(opcode)) + + def dump(self): + print("---------- Stack ----------") + self.c["RAM"].dump(self.c["LV"],self.c["SP"]) + print("---------------------------") diff --git a/components/ram.py b/components/ram.py new file mode 100644 index 0000000..c6d05bb --- /dev/null +++ b/components/ram.py @@ -0,0 +1,66 @@ +from components.ijvm import ijvm + +class Ram: + + def __init__(self,components,size): + self.data=dict() + self.lastAddr=size-1 + self.c=components + + def loadRamFile(self,filepath): + data=dict() + addr=0 + f=open(filepath,"r") + for line in f.readlines(): + line=line.rstrip() # remove \n + if line in ijvm: + data[addr]=int(ijvm[line]) + else: + data[addr]=int(line,0) + addr+=1 + f.close() + self.data=data + + def write(self): + addr=self.c["MAR"] + if addr>self.lastAddr: + raise ValueError("You get out of the ram by trying to set a value at address {}, max address is {}".format(addr,self.lastAddr)) + self.data[addr]=self.c["MDR"] + + def read(self): + addr=self.c["MAR"] + value=None + try: + value=self.data[addr] + except: + if addr>self.lastAddr: + raise ValueError("You get out of the ram by trying to get value at address {}, max address is {}".format(addr,self.lastAddr)) + if(value==None): + return(0) + return(value) + + def fetch(self): + addr=self.c["PC"] + value=None + try: + value=self.data[addr] + except: + if addr>self.lastAddr: + raise ValueError("You get out of the ram by trying to get value at address {}, max address is {}".format(addr,self.lastAddr)) + if(value==None): + return(0) + return(value) + + def dump(self): + print("------- RAM --------") + for key,value in self.data.items(): + #print("{}:{}".format(key,bin(value)[2:])) + print("{}:{}".format(key,value)) + print("--------------------") + + def dump(self,start,end): + for i in range(start,end+1): + try: + print("{}:{}".format(i,self.data[i])) + except: + print("{}:0".format(i)) diff --git a/micsim.py b/micsim.py new file mode 100755 index 0000000..1e4db48 --- /dev/null +++ b/micsim.py @@ -0,0 +1,17 @@ +#!/usr/bin/python + +from components.microprogram import Microprogram +from components.ram import Ram +from components.caretaker import Caretaker + +c=Caretaker() # Init components +RAM=Ram(c,5000) # Init ram +RAM.loadRamFile("./ram.txt") # Load Ram from file +c["RAM"]=RAM # Add ram to components + + +mic=Microprogram(c) # Create micro program +mic.run() # Run the micro program +mic.dump() # Dump ram + + diff --git a/ram.txt b/ram.txt new file mode 100644 index 0000000..5e4ce31 --- /dev/null +++ b/ram.txt @@ -0,0 +1,8 @@ +BIPUSH +5 +BIPUSH +2 +IADD +BIPUSH +10 +POP diff --git a/supports/mic1-architecture.gif b/supports/mic1-architecture.gif new file mode 100644 index 0000000..4a42f22 Binary files /dev/null and b/supports/mic1-architecture.gif differ