def _ProtoGenAlgorithm(self, arch: Architecture, state_sets, stablestates, maxdepth, deferfunc): newstates = 1 nestingdepth = 0 while newstates and nestingdepth < maxdepth: newstates = self._GenerateTransientStates(arch, state_sets, stablestates, deferfunc) # Update the traces arch.update_traces() nestingdepth += 1
def _ProtoGenV2(self, arch: Architecture, state_sets: StateSets, maxdepth: int): # Make trace trees start_state_set_to_access_trace_list_map, start_state_set_to_remote_trace_list_map = \ self.stable_state_trace_map(arch, state_sets) # Stalling newstates = True nestingdepth = 0 while newstates and nestingdepth < 2: newstates = False for state_set in state_sets: ret_val = self.concurrent_start_state_set_states( arch, state_sets[state_set], start_state_set_to_remote_trace_list_map) newstates = newstates or ret_val nestingdepth += 1 arch.update_traces() # Non-stalling enabled = False newstates = True nestingdepth = 0 while newstates and nestingdepth < maxdepth and (self.nonstalling or enabled): newstates = False for state_set in state_sets: ret_val = self.concurrent_end_state_set_states( arch, state_sets[state_set], start_state_set_to_remote_trace_list_map) newstates = newstates or ret_val nestingdepth += 1 arch.update_traces()
def _genAccessSendFunc(self, arch: Architecture, state: State): transitions = [trans for trans in state.getaccess() if trans.getaccess() and not trans.getinmsg()] \ + state.getevictmiss() trans_dict = MultiDict() for transition in transitions: trans_dict[transition.getguard()] = transition sendfctstr = "" for guard in trans_dict: ruleid = arch.get_unique_id_str() + "_" + str(state) + "_" + guard sendfctstr += self._genSendFunctionHeader( arch, ruleid, trans_dict[guard]) + self.nl return sendfctstr
def gen_access_send_func(self, arch: Architecture): sendfctstr = "" states = arch.get_states() for state in states: if [trans for trans in states[state].getaccess() if trans.getaccess() and not trans.getinmsg()] \ + states[state].getevictmiss(): break return sendfctstr for state in sorted(states.keys()): if len(states[state].getaccessmiss() + states[state].getevictmiss()): sendfctstr += self._genAccessSendFunc(arch, states[state]) + self.nl return sendfctstr
def _genSendFunctionHeader(self, arch: Architecture, ruleid, transitions: List[Transition]): arch_id = arch.get_unique_id_str() fctstr = "procedure " + self.tSEND + ruleid + \ "(" + self.cadr + ":" + self.kaddress + "; m:" + self.SetKey + arch_id + ")" + self.end all_var_name_dict = self._get_variable_names(arch) global_var_name_dict = arch.data_object.variables local_var_names_dict = self._filter_local_variables( all_var_name_dict, global_var_name_dict) self.func_local_var_names = list(local_var_names_dict.keys()) self.func_global_var_names = list(global_var_name_dict.keys()) fctstr += self._gen_local_variables(local_var_names_dict) fctstr += "begin" + self.nl fctstr += self.tab + "alias " + self.ccle + ": " + self.instsuf \ + arch_id + "[" + self.cmach + "]." + self.CLIdent \ + "[" + self.cadr + "] do" + self.nl fctstr += self.gen_single_trans_operation_str(arch_id, transitions) fctstr += "endalias" + self.end fctstr += "end" + self.end + self.nl return fctstr
def __init__(self, low_level: Level, high_level: Level, dbg_term: bool = False, dbg_graph: bool = False): Debug.__init__(self, dbg_term) self.dbg_graph = dbg_graph # for each ll state, add corresponding dir state and possible higher level cache states # higher level cache permissions are greater or equal to lower level state permissions # Lower level cache optimization # Optimization flag: Accesses that do hit in the higher level cache, do not cause the generation of self.ll_access_immed_hit = True # Higher level cache optimization # Optimization flag: Remote access are not conveyed to the lower level cache, if the hl trace final state has # lower access permissions than the current lower level caches self.hl_remote_immed_hit = True self.pessimistic_access = True self.complete_defer = False self.conservative_access_ll_request = True self.conservative_access_hl_request = True self.unique_id_str = "HIERA" self.unique_id = [self.unique_id_str] # Update messages to avoid conflicts for non-stalling implementations self.detect_message_dependencies(low_level, high_level) self.low_level: Level = copy.deepcopy(low_level) self.high_level: Level = copy.deepcopy(high_level) self.low_level.update_mach_name_operation(self.low_level.directory.get_unique_id_str(), self.unique_id_str) self.high_level.update_mach_name_operation(self.high_level.cache.get_unique_id_str(), self.unique_id_str) self.merge_data_objects() self.low_level.update_traces() self.high_level.update_traces() self.init_tuple: HieraStateTuple = HieraStateTuple(self.low_level.init_tuple, self.high_level.cache.init_state) ''' Get access mappings from lower level cache controller ''' self.ll_access_map = access_request_mapping(self.low_level.cache.state_sets) self.cc_dir_to_cc_state_map: Dict[State, List[State]] = {} self.cc_dir_to_dir_state_map: Dict[State, List[State]] = {} # Do the child init here HieraStateSpaceGen.__init__(self, self.low_level, self.high_level) """ Generate State Transitions """ HieraTransGen.__init__(self, self.low_level, self.high_level) HieraGraph.__init__(self, self.init_tuple, self.low_level, self.high_level) # Make new states based on new_state_tuples self.cc_dir_transitions = self.cc_dir_fsm_states() # Generate new stabel state nodes self.stable_states = self.create_cc_dir_states(self.access_state_tuples + self.remote_state_tuples + self.ll_evict_state_tuples + self.hl_evict_state_tuples) if self.dbg: self.print_debug_info() # New init_state_id new_state_name = self.new_state_name(self.init_tuple.ll_dir_start_state.state, self.init_tuple.hl_cc_start_state.state) # Make a new architecture self.low_level.directory = Architecture(self.low_level.directory.parser, self.low_level.directory.arch_name, self.cc_dir_transitions, list(self.stable_states.keys()), new_state_name, self.unique_id, self.low_level.directory.data_constant, self.low_level.directory.data_object ) # Make a new architecture self.high_level.cache = Architecture(self.high_level.directory.parser, self.high_level.cache.arch_name, self.cc_dir_transitions, list(self.stable_states.keys()), new_state_name, self.unique_id, self.high_level.cache.data_constant, self.high_level.cache.data_object ) self.replace_archs = [low_level.directory, high_level.cache]
def test_defer_arch(self, arch: Architecture) -> bool: return arch.test_token(self.tPUSH_HL_DEFER) or \ arch.test_token(self.tPUSH_LL_DEFER) or \ arch.test_token(self.tPUSH_STALL_DEFER)