def write_memory(self, value, position): """Escreve na memória um valor na posição position. Retorna True se a operação foi bem sucedida, False caso contrário. Keyword arguments: value -- Valor a ser escrito na memória position -- Posição de memória que value será escrito """ #Indicara a posicao a ser lida pos = None #Converte a posicao para inteiro if(type(position) == str): pos = convert_to_decimal(position) elif(type(position) == bytes): pos = int.from_bytes(position, "little") else: pos = position #Valor a ser escrito na memoria result = None #Coverte o resultado para bytes if (type(value) == str): result = convert_to_decimal(value) elif (type(value) == bytes): result = value else: result = value.to_bytes(value.bit_length(), "little") result_size = len(result) #Verifica se estamos tentando escrever mais do que a memoria suporta if (pos+result_size >= self.get_memory_size()): return False #Escrete os bytes na memoria for i in range(0, result_size): self._memory[pos+i] = result[i].to_bytes(1, "little") return True
def get_register_name_for_bus_b(self, instruction_string): """Retorna o nome do registrador acessado pelo barramento B atraves da parte B da instrucao em forma de string Keyword arguments: instruction_string -- a string que representa a parte B da instrucao (string) """ intRegister = convert_to_decimal(instruction_string) reg_names_for_b = ["mdr", "pc", "signed mbr", "unsigned mbr", "sp", "lv", "cpp", "tos", "opc"] return reg_names_for_b[intRegister].upper()
def next(self, next_address=""): """Vai para a próxima instrução e retorna True caso a operação seja bem sucedida e False caso contrário""" instruction = self.get_readable_instruction() # Caso nao foi passado nenhum valor como next_address, o proximo endereco especificado na instrucao e passado if (next_address == ""): self._cs_pos = convert_to_decimal(instruction["next_address"]) self._set_instruction(self._cs_pos) return True # Caso seja passado um valor como parametro de next address, este valor e convertido para inteiro if (type(next_address) == int): self._cs_pos = next_address self._set_instruction(self._cs_pos) return True if (type(next_address) == str): self._cs_pos = convert_to_decimal(next_address) self._set_instruction(self._cs_pos) return True return False
def read_memory(self, position, lines=1): """Ler uma posição ou mais posição de memória. Retorna um dicionário com a informação lida em bytes, string e array. Keyword arguments: position -- Posição inicial de memória a ser lida lines -- Número de posições a ser lida a partir de position """ #Verifica se esta tentando ler mais do que existe na memoria if (position >= self.get_memory_size()): return None #Indicara a posicao a ser lida pos = None #Converte a posicao para inteiro if (type(position) == str): pos = convert_to_decimal(position) elif (type(position) == bytes): pos = int.from_bytes(position, byteorder="little") else: pos = position #Resultado da leitura em bytes result_byte = b"" #Adiciona byte a byte os resultados for i in range(0, lines): result_byte += self._memory[pos+i] #Prepara resultado para ser mostrado em string result_str = '' for i in range(0, lines): int_value = int.from_bytes(self._memory[pos+i], "little") result_str += convert_to_bin(int_value)["bin_str"] #Prepara resultado para ser mostrado em listas result_arr = [] for i in range(0, lines): int_value = int.from_bytes(self._memory[pos+i], "little") result_arr += convert_to_bin(int_value)["bin_arr"] #Retorna o dicionario da leitura de 3 formas diferentes return { "byte": result_byte, "str": result_str, "arr": result_arr }
def get_register_for_bus_b(self, instruction_string): """Retorna o valor que o barramento B recebera atraves da parte B da instrucao em forma de string Keyword arguments: instruction_string -- a string que representa a parte B da instrucao (string) """ #Talvez seja necessario inverter a string #inv_reg = instruction_string[::-1] intRegister = convert_to_decimal(instruction_string) reg_names_for_b = ["mdr", "pc", "mbr", "mbr", "sp", "lv", "cpp", "tos", "opc"] reg_value = self.dict[reg_names_for_b[intRegister]] #Retorna o valor de MBR com sinal if(intRegister == 2 and reg_value > 256): reg_value = reg_value | (0b111111111111111111111111 << 8) return reg_value
def return_point(self): self.x = convert_to_decimal(self.x_chromosome) self.y = convert_to_decimal(self.y_chromosome) self.altitude = convert_to_decimal(self.z_chromosome) return self.x, self.y, self.altitude
def main(): # Recebe o nome do arquivo que deve ser carregado na memória principal file_path = sys.argv[1] # Objeto de Registradores registers = Reg() # Objeto da ULA ula = ULA() # Objeto de armazenamento de controle cs = Control_Storage() instruction = None # Objeto da Memória principal memory = Main_Memory(100000) instruction = None print("\t\t\t\tArquivo carregando na memória") # Carrega arquivo na memória principal if (memory.load_memory(file_path)): os.system('cls' if os.name == 'nt' else 'clear') else: print("Memória não pode ser carregada!") return while True: wait_for_clock() ####################################### PARTE 1: Decodificar ##################################### # Define a primeira instrução do microprograma a ser executada instruction = cs.get_readable_instruction() ####################################### PARTE 2: Barramentos ##################################### b = registers.get_register_for_bus_b(instruction["bus_b"]) ###################################### PRINT ##################################################### print("-----------------------------------------------------------") cs.get_instruction().print_instruction() print("\nRegistrador B: " + registers.get_register_name_for_bus_b(instruction["bus_b"])) print("\nNext Address Antes: " + str(convert_to_decimal(instruction["next_address"]))) print("\nREGISTRADORES ANTES:\n") registers.print_registers() ####################################### PARTE 3: ULA ############################################# #Atribui os barramentos A e B da ULA ula.set_inputs(registers.get_register_by_name("h"), b) InstULA = instruction["ula"] # Atribui e executa a instrucao da ULA ula.set_instruction(InstULA) print(ula.get_instruction_translation()) ula.execute_instruction() ####################################### PARTE 4: Registradores #################################### C = instruction["bus_c"] #Grava o resultado da ULA nos registradores especificados pela parte C da micro instrucao registers.set_register_by_inst(C, ula.get_result()) print(registers.get_registers_names_for_bus_c(C)) ####################################### PARTE 5: Memoria ########################################## m = instruction["memory"] #Realiza o Write na posicao MAR com o valor MDR if (m[0] == "1"): m_address = registers.get_register_by_name("mar") m_data = registers.get_register_by_name("mdr") memory.write_memory(m_data, m_address * 4) #Realiza o Read na posicao MAR e grava em MDR if (m[1] == "1"): m_address = registers.get_register_by_name("mar") m_data = memory.read_memory(m_address * 4, 4) m_data = int.from_bytes(m_data["byte"], "little") registers.set_register_by_name("mdr", m_data) #Realiza o Fetch na posicao PC e grava na em MBR if (m[2] == "1"): m_address = registers.get_register_by_name("pc") m_data = memory.fetch(m_address)["str"] m_data = convert_to_decimal(m_data) registers.set_register_by_name("mbr", m_data) ####################################### PARTE 6: Jumps ############################################ NextAdress = convert_to_decimal(instruction["next_address"]) J = instruction["jam"] #Realiza o JMPC realizando o OU bit a bit de MBR com NextAdress if (J[0] == '1'): NextAdress = NextAdress | registers.get_register_by_name("mbr") #JAMN e JAMZ abaixo, realizando o OU do nono bit do NextAdress (2^8 = 256) com o valor do bit que indica #se a ULA for zero(JAMZ) ou com a negacao desse bit(JAMN) if (J[1] == '1' and (not ula.is_zero()) and NextAdress < 256): NextAdress += 256 if (J[2] == '1' and ula.is_zero() and NextAdress < 256): NextAdress += 256 ####################################### PARTE 7: NEXT ADDRESS ##################################### # Vai para a próxima instrução cs.next(NextAdress) print("\nREGISTRADORES DEPOIS:\n") registers.print_registers() print("\nNext Address Depois: " + str(NextAdress) + "\n") print("-----------------------------------------------------------")