aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--components/__init__.py0
-rw-r--r--components/caretaker.py20
-rw-r--r--components/ijvm.py24
-rw-r--r--components/microprogram.py103
-rw-r--r--components/ram.py66
-rwxr-xr-xmicsim.py17
-rw-r--r--ram.txt8
-rw-r--r--supports/mic1-architecture.gifbin0 -> 92180 bytes
8 files changed, 238 insertions, 0 deletions
diff --git a/components/__init__.py b/components/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/components/__init__.py
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
--- /dev/null
+++ b/supports/mic1-architecture.gif
Binary files differ