parent
							
								
									4051d867a3
								
							
						
					
					
						commit
						4dcc3b8893
					
				| @ -0,0 +1 @@ | ||||
| */*.pdf | ||||
| @ -0,0 +1,136 @@ | ||||
| # Memory | ||||
| # 32-bit address | ||||
| # 8-bit cell | ||||
| # Register File | ||||
| # ·32 32-bit registers, with 2 read ports and 1 write portTest bench | ||||
| # / Add the number in memory address 0 and 1 to address 3 | ||||
| # Load r1, #0 | ||||
| # Load r2,#1 | ||||
| # Add r3, r1, r2 | ||||
| # Store r3, #3 | ||||
| import numpy as np | ||||
| import re | ||||
| import random | ||||
| class register_file: | ||||
|      | ||||
|     def __init__(self , size) -> None: | ||||
|         self.regs = np.array([0] * size , dtype=np.int32) | ||||
|         self.size = size | ||||
|      | ||||
|     def read(self , idx1 : int , idx2 : int) -> tuple:# 2 read port | ||||
|             if idx1 < 0 or idx1 >= self.size or idx2 < 0 or idx2 >= self.size: | ||||
|                 raise IndexError(f"The index is out of range") | ||||
|              | ||||
|             return (self.regs[idx1] , self.regs[idx2]) | ||||
| 
 | ||||
|     def write(self , idx : int , value : np.int32) -> None:# 1 write port | ||||
|         if idx < 0 or idx >= self.size: | ||||
|             raise IndexError("The index is out of range") | ||||
|          | ||||
|         if value < -2**31 or value > 2**31 - 1: | ||||
|             raise ValueError("The value is out of range") | ||||
|          | ||||
|         self.regs[idx] = value | ||||
| 
 | ||||
|     def info(self) -> None: | ||||
|         print(f"register file : {self.regs}") | ||||
| 
 | ||||
| class memory: | ||||
|     def __init__(self , size): | ||||
|         self.size = size | ||||
|         self.mem = {key : np.int8(0) for key in range(10)}#8-bit cell | ||||
|         # use dictionary to simulate 2**32 byte-memory | ||||
| 
 | ||||
|     def reset(self): | ||||
|         self.mem = {key : np.int8(0) for key in self.mem} | ||||
|      | ||||
|     def info(self) -> None: | ||||
|         print(f"memory : {self.mem}") | ||||
|      | ||||
|     def read(self , idx : int) -> np.int8: | ||||
|         if idx < 0 or idx >= self.size: | ||||
|             raise IndexError("The index is out of range") | ||||
|          | ||||
|         if idx not in self.mem: | ||||
|             self.mem[idx] = np.int8(0) | ||||
|         return self.mem[idx] | ||||
|      | ||||
|     def write(self , idx , value : np.int8) -> None: | ||||
|         if idx < 0 or idx >= self.size: | ||||
|             raise IndexError("The index is out of range") | ||||
|          | ||||
|         if(value < -128 or value > 127): | ||||
|             raise ValueError("The value is out of range") | ||||
|          | ||||
|         self.mem[idx] = value | ||||
| 
 | ||||
| 
 | ||||
| class instruction: | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def Load(ins : list , immediate: bool = False) -> None: | ||||
|         regfile.write(ins[1] , mem.read(ins[2])) | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def Loadi(ins : list):#load immediate to register , just for test , style of instruction : Loadi r1 , i100 | ||||
|         regfile.write(ins[1] , ins[2]) #to fix : merge into Load instruction by adding flag immediate , maybe | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def Store(ins : list) -> None: | ||||
|         mem.write(ins[2] , regfile.read(ins[1] , 0)[0])#just use one read port of regfile | ||||
|      | ||||
|     @staticmethod | ||||
|     def Add(ins : list) -> None: | ||||
|         r1 , r2 = regfile.read(ins[2] , ins[3]) | ||||
|         regfile.write(ins[1] , r1 + r2) | ||||
| 
 | ||||
|     def exec_ins(self , ins : list) -> None: | ||||
|         target_ins = getattr(type(self) , ins[0]) | ||||
|         if target_ins is None: | ||||
|             raise RuntimeError("the error instruction {}".format(ins[0])) | ||||
|         target_ins(ins) | ||||
|          | ||||
|     @staticmethod | ||||
|     def parse_instruction(instruc : str) -> list: | ||||
|         #parse the instruction | ||||
|         _ins = re.split(r'[ ,]+' , instruc)# split the string by space and comma | ||||
|         ins = [_ins[0]] | ||||
|         for elem in _ins: | ||||
|             if elem[0] == 'r' or elem[0] == '#' or elem[0] == 'i':#get the bias of address | ||||
|                 ins.append(int(elem[1:])) | ||||
| 
 | ||||
|         return ins | ||||
| 
 | ||||
| class testbench: | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def memory_random_flip(): | ||||
|         mem.mem = {key : random.randint(-10,10) for key in mem.mem} | ||||
|      | ||||
|     @staticmethod | ||||
|     def test(): | ||||
|         testbench.memory_random_flip() | ||||
|         mem.info() | ||||
|         test_instr = ['Load r1, #0' , 'Load r2,#1' , 'Add r3, r1, r2' , 'Store r3, #3'] | ||||
|         for ins in test_instr: | ||||
|             _ins = instruction.parse_instruction(ins) | ||||
|             instruc.exec_ins(_ins) | ||||
| 
 | ||||
|         mem.info() | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|      | ||||
|     global regfile , mem , instruc | ||||
|     regfile = register_file(32)#32 32-bit registers | ||||
|     mem = memory(2 ** 32)# 32-bit address memory | ||||
|     instruc = instruction() | ||||
| 
 | ||||
|     testbench.test() | ||||
|     while True: | ||||
|         _inst = input('>') | ||||
|         inst  = instruc.parse_instruction(_inst) | ||||
|         instruc.exec_ins(inst) | ||||
|         mem.info() | ||||
|         regfile.info() | ||||
											
												Binary file not shown.
											
										
									
								
					Loading…
					
					
				
		Reference in new issue