aboutsummaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/__init__.py0
-rw-r--r--components/caretaker.py34
-rw-r--r--components/ijvm.py30
-rw-r--r--components/microprogram.py202
-rw-r--r--components/ram.py94
5 files changed, 0 insertions, 360 deletions
diff --git a/components/__init__.py b/components/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/components/__init__.py
+++ /dev/null
diff --git a/components/caretaker.py b/components/caretaker.py
deleted file mode 100644
index ab20fba..0000000
--- a/components/caretaker.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/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):
- if key=="MBRU": # If we ask for unsigned
- return(abs(self.objects["MBR"]))
- elif key== "MBR":
- if (self.objects[key]>>7)==1: # If it a negative number (2 complement)
- return(-((self.objects[key]-1)^0xFF)) # transforme bin negative number to python negative number
- else:
- return(self.objects[key])
- return(self.objects[key])
-
- def __setitem__(self,key,value):
- if key!="RAM":
- if value > (2**32) and key!="MBR" and key!="MBRU": # Check value fit in word
- print("Warning word overflow: value {} on register {}".format(value,key))
- value=value%(2**32) # Force to fit in word
- elif value > (2**8) and key=="MBR" and key=="MBRU": # Check value fit in byte
- print("Warning byte overflow: value {} on register {}".format(value,key))
- value=value%256 # Force to fit in byte
- self.objects[key]=value
-
- def items(self):
- return(self.objects.items())
-
diff --git a/components/ijvm.py b/components/ijvm.py
deleted file mode 100644
index 86f5f63..0000000
--- a/components/ijvm.py
+++ /dev/null
@@ -1,30 +0,0 @@
-
-# Quick link about opcode: https://users-cs.au.dk/bouvin/dComArk/2015/noter/Note_2/#Instructions
-
-# 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
-})
-
-# Add extras instructions
-ijvm["OUT"]=0x23 # Print next byte as char
-ijvm["HALT"]=0x2F # Stop simulator
diff --git a/components/microprogram.py b/components/microprogram.py
deleted file mode 100644
index 6147921..0000000
--- a/components/microprogram.py
+++ /dev/null
@@ -1,202 +0,0 @@
-
-from components.ijvm import ijvm
-
-class Microprogram:
-
- def __init__(self,components):
- self.c=components # Link components to microprogram
- if self.c["RAM"]==None: # Check if RAM is initialize
- raise RuntimeError("Microprogram initialization fail, RAM is not initialized")
-
- def run(self):
- """
- Start microprogram
- """
- 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 after fetch
- if self.exec()==1: # Execute opcode and halt if return code is 1
- break;
-
- def fetch(self):
- """
- Fetch next byte from memory into MBR
- """
- opcode=self.c["RAM"].fetch()
- self.c["MBR"]=opcode # Opcode to MBR
-
- def rd(self):
- """
- Read data into memory
- """
- data=self.c["RAM"].read()
- self.c["MDR"]=data
-
- def wr(self):
- """
- Write data into memory
- """
- self.c["RAM"].write()
-
- def exec(self): # TODO: Implement opcode
- """
- Execute next opcode
- """
- opcode=self.c["MBRU"] # Get loaded OpCode (/!\ We used MBRU not MBR because MBR is signed)
- 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"] & 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"] | 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"]
- elif opcode==ijvm["ILOAD"]:
- self.fetch();self.c["PC"]+=1 # Fetch local variable to push onto the stack
- self.c["H"]=self.c["LV"]
- self.c["MAR"]=self.c["MBRU"]+self.c["H"]
- self.rd()
- self.c["SP"]+=1
- self.c["MAR"]=self.c["SP"]
- self.wr()
- self.c["TOS"]=self.c["MDR"]
- elif opcode==ijvm["ISTORE"]:
- self.fetch();self.c["PC"]+=1 # Fetch local variable offset where to store
- self.c["H"]=self.c["LV"]
- self.c["MAR"]=self.c["MBRU"]+self.c["H"]
- self.c["MDR"]=self.c["TOS"]
- self.wr()
- self.c["SP"]-=1
- self.c["MAR"]=self.c["SP"]
- 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.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.c["H"]=self.c["MDR"]
- self.c["MDR"]=self.c["MBR"]+self.c["H"]
- self.wr()
- elif opcode==ijvm["GOTO"]:
- self.fetch();self.c["PC"]+=1 # Fetch first byte
- self.c["OPC"]=self.c["PC"]-1
- self.c["H"]=self.c["MBR"]<<8
- self.fetch();self.c["PC"]+=1 # Fetch second byte
- self.c["H"]=self.c["MBRU"]|self.c["H"]
- 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
- elif opcode==ijvm["IFEQ"]:
- self.c["SP"]=self.c["SP"]-1
- self.c["MAR"]=self.c["SP"]
- self.c["OPC"]=self.c["TOS"]
- self.rd()
- self.c["TOS"]=self.c["MDR"]
- if self.c["OPC"]==0:
- self.T()
- else:
- self.F()
- elif opcode==ijvm["IFLT"]:
- self.c["SP"]=self.c["SP"]-1
- self.c["MAR"]=self.c["SP"]
- self.c["OPC"]=self.c["TOS"]
- self.rd()
- self.c["TOS"]=self.c["MDR"]
- if self.c["OPC"]<0:
- self.T()
- else:
- self.F()
- elif opcode==ijvm["HALT"]:
- return(1)
- else:
- if opcode in ijvm:
- print("Instruction {} not yet implemented.".format(ijvm[opcode]))
- else:
- 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"
- self.fetch();self.c["PC"]+=1 # exactly like GOTO implementation
- self.c["OPC"]=self.c["PC"]-1 # exactly like GOTO implementation
- ###### GOTO2 #####
- self.c["H"]=self.c["MBR"]<<8
- self.fetch();self.c["PC"]+=1 # Fetch second byte
- self.c["H"]=self.c["MBRU"]|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"
- self.fetch();self.c["PC"]+=1 # Needed because memory access take 1 cycle in simulation
- self.c["PC"]=self.c["PC"]+1
-
- def dump(self):
- """
- Print RAM, stack and registers
- """
- print("-------------- RAM --------------")
- self.c["RAM"].dump()
- print("------------- Stack -------------")
- self.c["RAM"].dumpRange(self.c["LV"]*4,self.c["SP"]*4,4) # Convert address to 32bits value
- print("----------- Registers -----------")
- for key,value in self.c.items():
- if key!="RAM":
- print("{}={}".format(key,value))
- print("---------------------------------")
diff --git a/components/ram.py b/components/ram.py
deleted file mode 100644
index dd99ada..0000000
--- a/components/ram.py
+++ /dev/null
@@ -1,94 +0,0 @@
-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):
- """
- Load a Ram file into self.data
- """
- 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:
- try:
- value=int(line,0)
- except:
- raise ValueError("Invalide RAM entry: Address {} value {}".format(addr,line))
- if value>255:
- raise ValueError("Ram contain values that does not fit in a byte: value {} at address {}".format(value,addr))
- data[addr]=value
- addr+=1
- f.close()
- self.data=data
-
- def write(self):
- """
- Write data to memory based Mic-1 architecture
- """
- addr=self.c["MAR"]*4 # Don't forget MAR address 32bits block of memory
- 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))
- #### Little endian ####
- self.data[addr]=self.c["MDR"] & 0xFF
- self.data[addr+1]=self.c["MDR"] & 0xFF00
- self.data[addr+2]=self.c["MDR"] & 0xFF0000
- self.data[addr+3]=self.c["MDR"] & 0xFF000000
-
-
- def read(self):
- """
- Read data from memory based Mic-1 architecture
- """
- addr=self.c["MAR"]*4 # Don't forget MAR address 32bits block of memory
- value=None
- try:
- #### Little endian ####
- value=(self.data[addr+3]<<24)|(self.data[addr+2]<<16)|(self.data[addr+1]<<8)|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):
- """
- Fetch next byte from memory based Mic-1 architecture
- """
- 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):
- """
- Simple dump helper
- """
- for key,value in self.data.items():
- #print("{}:{}".format(key,bin(value)[2:]))
- print("{}:{}".format(key,value))
-
- def dumpRange(self,start,end,step):
- """
- Another dump helper
- """
- for i in range(start,end+1,step):
- try:
- print("{}:{}".format(i,self.data[i]))
- except:
- print("{}:0".format(i))