From 41ca619297f2069a6913e443ca1ada4fc371b57a Mon Sep 17 00:00:00 2001 From: pygpoul32 <973207921@qq.com> Date: Tue, 22 Nov 2022 21:26:24 +0800 Subject: [PATCH] ADD file via upload --- 06/tomasulo-last.py | 745 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 745 insertions(+) create mode 100644 06/tomasulo-last.py diff --git a/06/tomasulo-last.py b/06/tomasulo-last.py new file mode 100644 index 0000000..2d1fad1 --- /dev/null +++ b/06/tomasulo-last.py @@ -0,0 +1,745 @@ +""" +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 21/11/2022 下午 8:12 +# @Author : +# @File : tomasulo.py +# @Description : +""" + +import numpy as np +from typing import List + + +class Normalizer: + def __init__(self): + self.__instructions = None + self.__out = None + + def __replace(self): + self.__out = [i.split(r'//')[0] for i in self.__instructions] + self.__out = [i.replace(':', ': ', -1) for i in self.__out] + self.__out = [i.replace(',', ', ', -1) for i in self.__out] + self.__out = [i.replace('/t', ' ', -1) for i in self.__out] + self.__out = [i.replace('#', '', -1) for i in self.__out] + self.__out = [i.replace('(', ',', -1) for i in self.__out] + self.__out = [i.replace(')', ',', -1) for i in self.__out] + self.__out = [i.replace('F', 'R', -1) for i in self.__out] + + for i in range(len(self.__out)): + while True: + if ' ' in self.__out[i]: + self.__out[i] = self.__out[i].replace( + ' ', ' ', -1) + else: + break + + self.__out = [i.replace(' ,', ',', -1) for i in self.__out] + self.__out = [i.replace(', ', ',', -1) for i in self.__out] + + def __delete_empty(self): + self.__out = [i[1:] if i[0] == ' ' else i for i in self.__out] + + temp = self.__out + self.__out = [] + + for i in temp: + if not i == '': + self.__out.append(i) + + def instructions_input(self, _instructions: List[str]): + self.__instructions = _instructions + + def get_out(self): + return self.__out + + def run(self): + self.__replace( ) + self.__delete_empty( ) + + +class Spliter: + def __init__(self): + self.__instructions = None + self.__out = None + + def __get_pointer(self): + for i in range(len(self.__instructions)): + if ':' in self.__instructions[i]: + self.__out[i]['pointer'] = \ + self.__instructions[i].split(':')[0] + self.__instructions[i] = \ + self.__instructions[i].split(':')[1][1:] + else: + self.__out[i]['pointer'] = '' + + def __get_mnemonic(self): + for i in range(len(self.__instructions)): + self.__out[i]['mnemonic'] = \ + self.__instructions[ + i][: self.__instructions[i].find(' ')] + self.__instructions[i] = \ + self.__instructions[ + i][self.__instructions[i].find(' ') + 1:] + + def __get_parameters(self): + for i in range(len(self.__instructions)): + self.__out[i]['parameters'] = [ + self.__instructions[ + i][: self.__instructions[i].find(',')]] + self.__instructions[i] = \ + self.__instructions[ + i][self.__instructions[i].find(',') + 1:] + self.__out[i]['parameters'].append( + self.__instructions[ + i][: self.__instructions[i].find(',')]) + self.__out[i]['parameters'].append( + self.__instructions[ + i][self.__instructions[i].find(',') + 1:]) + + if self.__out[i]['parameters'][-1][-1] == ',': + self.__out[i]['parameters'][-1] = \ + self.__out[i]['parameters'][-1][: -1] + + for i in range(len(self.__instructions)): + for j in range(len(self.__out[i]['parameters'])): + self.__out[i]['parameters'][j] = \ + self.__out[i]['parameters'][j].split(r' ')[0] + + def instructions_input(self, _instructions: List[str]): + self.__instructions = _instructions + + def get_out(self): + return self.__out + + def run(self): + self.__out = [{} for _ in range(len(self.__instructions))] + self.__get_pointer( ) + self.__get_mnemonic( ) + self.__get_parameters( ) + + +class Table: + def __init__(self, _name: str = "table"): + self.name = _name + + def set_name(self, _name: str): + self.name = _name + + def get_name(self): + return self.name + + +class InstructionStatus(Table): + def __init__(self): + super( ).__init__( ) + self.__index = [] + self.__keys = ["Ins", "FI", "IS", "EX", "WR", "Unit"] + + def push(self, _instruction: dict): + self.__index = np.append(self.__index, + {i: False for i in self.__keys}) + self.__index[-1]["Ins"] = _instruction.copy( ) + + def get_table(self): + return self.__index + + def clear(self): + self.__index = [] + + +class ReservationStation(Table): + def __init__(self): + super( ).__init__( ) + self.__index = {} + self.__keys = ["Busy", "Op", "Vj", "Vk", "Qj", "Qk", "A"] + self.__unit_name = [] + self.__unit_name.extend( + ["LOAD" + str(i + 1) for i in range(2)]) + self.__unit_name.extend( + ["ADD" + str(i + 1) for i in range(3)]) + self.__unit_name.extend( + ["MULT" + str(i + 1) for i in range(2)]) + self.__unit_name.extend( + ["STORE" + str(i + 1) for i in range(2)]) + self.__index = {i: { + j: False for j in self.__keys} for i in self.__unit_name} + + def get_table(self): + return self.__index + + +class RegisterResultStatus(Table): + def __init__(self): + super( ).__init__( ) + self.__index = None + self.__keys = [] + + for i in range(32): + self.__keys.append(str(i)) + + self.__index = {i: "" for i in self.__keys} + + def get_table(self): + return self.__index + + +class Analyzer: + def __init__(self): + self.__instructions = None + self.__out = [] + self.__dict_steps = { + 'L.D': 2, + 'MUL.D': 10, + 'S.D': 2, + } + self.__dict_FU = { + 'L.D': 'LOAD', + 'MUL.D': 'MUL', + 'S.D': 'STORE', + } + + def __get_RR(self): + for i in range(len(self.__out)): + if self.__out[i]['Ins']['mnemonic'] != 'S.D': + self.__out[i]["W"] = \ + self.__instructions[i]['parameters'][0][1:] + + for j in range(2): + if 'R' in self.__out[i]['Ins']['parameters'][1 + j]: + self.__out[i]["R"].append( + self.__instructions[i][ + 'parameters'][1 + j][1:]) + else: + self.__out[i]["R"].append('') + + def instructions_input(self, _instructions: List[str]): + self.__instructions = _instructions + + for instruction in self.__instructions: + if instruction["mnemonic"] == "BNE" or \ + instruction["mnemonic"] == "DADDUI": + continue + else: + self.__out.append({ + "Ins": instruction.copy( ), + "FU": self.__dict_FU[instruction["mnemonic"]], + "W": '', + "R": [], + "steps": self.__dict_steps[ + instruction["mnemonic"]]}) + + def get_out(self) -> dict: + return self.__out + + def run(self): + self.__get_RR( ) + + +class Tomasulo: + def __init__(self): + self.__change = [] + self.__tables = { + "instruction_status": InstructionStatus( ), + "reservation_station": ReservationStation( ), + "register_result_status": RegisterResultStatus( ) + } + self.__func_dict = { + 'IS': self.__issue, + 'EX': self.__execute, + 'WR': self.__write + } + self.__loop = [] + self.__record = [] + self.__loop_time = 2 + self.__times = 0 + self.__time = 0 + self.__run = [] + self.__index = [] + self.__record_dict = { + "instruction_status": [], + "reservation_station": [], + "register_result_status": [] + } + + def __issue(self): + if not len(self.__tables["instruction_status"].get_table( )): + for _ in range(self.__loop_time): + self.__times += 1 + + for i in range(len(self.__loop)): + self.__tables["instruction_status"].push( + _instruction = self.__index[ + _ * len(self.__loop) + i]) + self.__tables["instruction_status"].get_table( )[ + -1]['FI'] = self.__times + + for instruction in self.__tables[ + "instruction_status"].get_table( ): + if instruction['Ins']['W'] != instruction[ + 'Ins']['Ins'][ + 'parameters'][0][ + 1:]: + instruction['Ins']['W'] = \ + instruction['Ins']['Ins']['parameters'][0][1:] + + iteration = [False for _ in range(self.__loop_time)] + + for i in range(len( + self.__tables["instruction_status"].get_table( ))): + if not self.__tables[ + "instruction_status"].get_table( )[i]['IS']: + if iteration[(self.__tables[ + "instruction_status" + ].get_table( )[i]['FI'] - 1) % + self.__loop_time]: + continue + + instruction = \ + self.__tables[ + "instruction_status"].get_table( )[i]['Ins'] + op_FU = instruction['FU'] + reg_R = [instruction['R'][0], instruction['R'][1]] + reg_W = instruction['W'] + mnemonic = instruction['Ins']['mnemonic'] + + if reg_W and self.__tables[ + "register_result_status"].get_table( )[reg_W]: + position = -1 + used = [False for _ in range(32)] + + for j in range(0, (i // len(self.__loop) + 1) + * len(self.__loop)): + for k in range(3): + if 'R' in self.__tables[ + "instruction_status"].get_table( )[j][ + 'Ins']['Ins']['parameters'][k]: + used[int(self.__tables[ + "instruction_status" + ].get_table( )[j]['Ins'][ + 'Ins']['parameters'][ + k][1:])] = True + + for j in range(32): + if not self.__tables[ + "register_result_status"].get_table( )[ + str(j)] and not used[j]: + position = j + break + + if position == -1: + iteration[self.__tables[ + "instruction_status" + ].get_table( )[i]['FI'] - 1] = True + continue + + for j in range(i, (i // len(self.__loop) + 1) * + len(self.__loop)): + if self.__tables[ + "instruction_status"].get_table( )[j][ + 'Ins']['W'] == reg_W: + self.__tables[ + "instruction_status"].get_table( )[j][ + 'Ins']['W'] = str(position) + self.__tables[ + "instruction_status"].get_table( )[j][ + 'Ins']['Ins']['parameters'][0] = \ + 'R' + str(position) + + for k in range(2): + if self.__tables[ + "instruction_status"].get_table( )[j][ + 'Ins']['R'][k] == reg_W: + self.__tables[ + "instruction_status"].get_table( + )[j]['Ins']['R'][k] = str(position) + self.__tables[ + "instruction_status"].get_table( + )[j]['Ins']['Ins']['parameters'][ + 1 + k] = 'R' + str(position) + + instruction = self.__tables[ + "instruction_status"].get_table( )[i]['Ins'] + reg_R = [instruction['R'][0], instruction['R'][1]] + reg_W = instruction['W'] + + self.__run[i] = False + self.__tables[ + "instruction_status"].get_table( )[i]['IS'] = \ + self.__time + + for function_unit in self.__tables[ + "reservation_station"].get_table( ): + if op_FU in function_unit: + if self.__tables[ + "reservation_station"].get_table( )[ + function_unit]['Busy']: + continue + else: + self.__tables[ + "instruction_status"].get_table( )[i][ + 'Unit'] = function_unit + unit = self.__tables[ + "reservation_station"].get_table( )[ + function_unit] + unit['Busy'] = True + unit['Op'] = mnemonic + + for i in range(2): + if not reg_R[i]: + continue + if self.__tables[ + "register_result_status" + ].get_table( )[reg_R[i]]: + unit['Q' + chr(ord('j') + i)] = \ + self.__tables[ + "register_result_status" + ].get_table( )[reg_R[i]] + else: + unit['V' + chr(ord('j') + i)] = \ + 'R' + reg_R[i] + + self.__tables[ + "register_result_status" + ].get_table( )[reg_W] = function_unit + break + + break + + def __execute(self): + for i in range(len( + self.__tables["instruction_status"].get_table( ))): + if not self.__run[i]: + continue + + if self.__tables[ + "instruction_status"].get_table( )[i]['IS']: + unit = self.__tables[ + "reservation_station"].get_table( )[ + self.__tables["instruction_status"].get_table( )[ + i]['Unit']] + + if not unit['Qj'] and not unit['Qk'] and \ + self.__tables["instruction_status"].get_table( + )[i]['Ins']['steps']: + self.__tables["instruction_status"].get_table( + )[i]['Ins']['steps'] -= 1 + + if not self.__tables[ + "instruction_status"].get_table( )[i][ + 'Ins']['steps']: + self.__tables["instruction_status"].get_table( + )[i]['EX'] = self.__time + self.__run[i] = False + + def __write(self): + for i in range(len( + self.__tables["instruction_status"].get_table( ))): + if not self.__run[i]: + continue + + if self.__tables[ + "instruction_status"].get_table( )[i]['EX'] and not \ + self.__tables[ + "instruction_status"].get_table( )[i]['WR']: + self.__tables["register_result_status"].get_table( )[ + self.__tables["instruction_status"].get_table( )[ + i]['Ins']['W']] = '' + self.__tables["instruction_status"].get_table( )[i][ + 'WR'] = self.__time + unit = self.__tables[ + "reservation_station"].get_table( )[ + self.__tables["instruction_status"].get_table( )[ + i]['Unit']] + unit['Busy'] = False + unit['Op'] = '' + unit['Vj'] = '' + unit['Vk'] = '' + unit['Qj'] = '' + unit['Qk'] = '' + unit['A'] = '' + + def set_change(self, _change: List[dict]): + self.__change = _change + + def set_loop(self, _loop: List[dict]): + self.__loop = _loop + + def set_index(self, _loop: List[dict]): + for i in _loop: + self.__index.append(i.copy( )) + + def run(self, _time: int): + self.__run = [True for _ in range(self.__loop_time * + len(self.__loop))] + self.__time = _time + self.__issue( ) + self.__execute( ) + self.__write( ) + + for key in self.__tables['reservation_station'].get_table( ): + unit = self.__tables[ + 'reservation_station'].get_table( )[key] + + for i in range(2): + if unit['Q' + chr(ord('j') + i)]: + unit_name = unit['Q' + chr(ord('j') + i)] + + if unit_name not in self.__tables[ + 'register_result_status'].get_table( + ).values( ): + unit['Q' + chr(ord('j') + i)] = '' + unit['V' + chr(ord('j') + i)] = unit_name + + if 'LOAD' in key: + if not unit['A']: + for i in range(2): + if unit['V' + chr(ord('j') + i)]: + unit['A'] = unit['V' + chr(ord('j') + i)] + unit['V' + chr(ord('j') + i)] = '' + break + + time = 0 + + for i in range( + len(self.__loop) * self.__loop_time): + if key == self.__tables[ + 'instruction_status'].get_table( )[i][ + 'Unit']: + time = (self.__tables[ + 'instruction_status' + ].get_table( )[i]['FI'] - 1) % \ + self.__loop_time + break + + for change in self.__change: + if unit['A'] and time and \ + change['REG'] == unit['A'][1:]: + unit['A'] += ' ' + str(change['C'] * time) + break + + if 'STORE' in key: + for i in range( + len(self.__loop) * self.__loop_time): + if key == self.__tables[ + 'instruction_status'].get_table( )[i][ + 'Unit']: + time = (self.__tables[ + 'instruction_status'].get_table( + )[i]['FI'] - 1) % self.__loop_time + break + + for change in self.__change: + for j in range(2): + if unit['V' + chr(ord('j') + j)] and \ + time and change['REG'] == \ + unit['V' + chr(ord('j') + j)][1:]: + unit['V' + chr(ord('j') + j)] += \ + ' ' + str(change['C'] * time) + break + + flag = False + + for instruction in self.__tables[ + 'instruction_status'].get_table( ): + if not (instruction['IS'] and instruction['EX'] and + instruction['WR']): + flag = True + + self.__record_dict["instruction_status"].append( + [{'Ins': i['Ins']['Ins'], 'FI': i['FI'], 'IS': i['IS'], + 'EX': i['EX'], 'WR': i['WR']} + for i in self.__tables[ + 'instruction_status'].get_table( )]) + reservation_station = [ + np.append([i], [self.__tables[ + 'reservation_station'].get_table( )[ + i][j] for j in self.__tables[ + 'reservation_station'].get_table( )[ + i]]) + for i in self.__tables[ + 'reservation_station'].get_table( )] + self.__record_dict[ + "reservation_station"].append(reservation_station) + register_result_status = [ + self.__tables['register_result_status'].get_table( )[i] + for i in self.__tables[ + 'register_result_status'].get_table( )] + self.__record_dict[ + "register_result_status"].append(register_result_status) + + if not flag: + self.__tables['instruction_status'].clear( ) + + def get_out(self): + return self.__record_dict + + +def run(_instructions: List[str]) -> dict: + normalizer = Normalizer( ) + spliter = Spliter( ) + analyzer = Analyzer( ) + tomasulo = Tomasulo( ) + + normalizer.instructions_input(_instructions) + normalizer.run( ) + + spliter.instructions_input(normalizer.get_out( )) + spliter.run( ) + + loop = [] + change = [{'REG': '', 'C': 0}] + + for instruction in spliter.get_out( ): + if instruction['mnemonic'] == 'BNE': + pointer = instruction['parameters'][-1] + + for _instruction in spliter.get_out( ): + if pointer == _instruction['pointer']: + for _instruction in spliter.get_out( ): + if _instruction['mnemonic'] == 'DADDUI': + break + + loop.append(_instruction) + break + + if instruction['mnemonic'] == 'DADDUI': + change[0]['REG'] = instruction['parameters'][0][1:] + change[0]['C'] = int(instruction['parameters'][-1]) + + analyzer.instructions_input(loop) + analyzer.run( ) + + tomasulo.set_change(change) + tomasulo.set_loop(analyzer.get_out( )) + + normalizer = Normalizer( ) + spliter = Spliter( ) + analyzer = Analyzer( ) + + _instructions = _instructions[: -2] + _instructions.extend(_instructions) + + normalizer.instructions_input(_instructions) + normalizer.run( ) + + spliter.instructions_input(normalizer.get_out( )) + spliter.run( ) + + analyzer.instructions_input(spliter.get_out( )) + analyzer.run( ) + tomasulo.set_index(analyzer.get_out( )) + + for time in range(1, 43): + tomasulo.run(time) + + return tomasulo.get_out( ) + + +def show(_table: dict): + IS = _table['instruction_status'] + FUS = _table['reservation_station'] + RRS = _table['register_result_status'] + + cycles = len(IS) + + for cycle in range(cycles): + print('*' * 100) + print('*', ' ' * 8, end = '') + cycle_str = 'Cycle ' + str(cycle + 1) + print(cycle_str, end = '') + print(' ' * (88 - len(cycle_str)), '*') + print('*' * 100) + + print('*', ' ' * 3, end = '') + print('instruction status', ' ' * 74, '*') + print('*' + '-' * 98 + '*') + + print('*' + ' ' * 8, end = '') + print(' instruction ', end = '') + print(' ' * 5 + 'From Iteration', end = '') + print(' ' * 5 + 'Read Oper', end = '') + print(' ' * 6 + 'Exec Comp', end = '') + print(' ' * 5 + 'Write Result *') + + for ins in IS[cycle]: + print('*' + ' ' * 8, end = '') + index = ins['Ins']['mnemonic'] + ' ' * ( + 8 - len(ins['Ins']['mnemonic'])) + for i in ins['Ins']['parameters']: + index += ' ' + i + ' ' * (4 - len(i)) + index += ' ' * 10 + index += str(ins['FI']) + ' ' * (15 - len(str(ins['FI']))) + index += str(ins['IS']) + ' ' * (15 - len(str(ins['IS']))) + index += str(ins['EX']) + ' ' * (15 - len(str(ins['EX']))) + index += str(ins['WR']) + ' ' * ( + 12 - len(str(ins['WR']))) + '*' + index = index.replace('False', ' ' * 5, -1) + print(index) + + print('*' * 100) + + print('*', ' ' * 3, end = '') + print('reservation station', ' ' * 73, '*') + print('*' + '-' * 98 + '*') + + print('*' + ' ' * 8, end = '') + label = ['Name', 'Busy', 'Op', 'Fi', 'Fj', 'Fk', 'Qj', 'A'] + index = "" + for i in label: + index += i + ' ' * (11 - len(i)) + print(index, end = ' *\r\n') + + for fus in FUS[cycle]: + print('*' + ' ' * 8, end = '') + index = "" + for i in range(len(fus)): + if fus[i] == '1' or not fus[i] or fus[i] == 'False': + fus[i] = '' + elif fus[i] is True or fus[i] == 'True': + fus[i] = 'Yes' + for i in range(3): + if fus[3 + i]: + fus[3 + i] = 'R' + fus[3 + i] + for label in fus: + index += label + ' ' * (11 - len(label)) + print(index, end = ' *\r\n') + + print('*' * 100) + + print('*', ' ' * 3, end = '') + print('register result status', ' ' * 70, '*') + print('*' + '-' * 98 + '*') + + count = 0 + index = "" + value = "" + for i in RRS[cycle]: + if count % 8 == 0: + print(index, end = '') + if count: + print(' *') + print(value, end = '') + if count: + print(' *') + index = '*' + ' ' * 8 + value = '*' + ' ' * 8 + index += 'R' + str(count) + ' ' * (10 - len(str(count))) + value += i + ' ' * (11 - len(i)) + count += 1 + + print('*' * 100) + print('\r\n\r\n') + + +if __name__ == '__main__': + instructions = [ + "LOOP: L.D F0, 0 (R1)", + " MUL.D F4, F0, F2 ", + " S.D 0 (R1) F4 ", + " DADDUI R1, R1, #-8 ", + " BNE R1, R2, LOOP", + ] + + tables = run(instructions) + show(_table = tables)