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