def process_operation(self, operation: CommonTree, arch: str, transition: Transition): inmsgtype = transition.getrefguard() if transition.getrefguard( ) else transition.getguard() if operation.getText() == self.tASSIGN: return self._genArchAssignment(operation, arch, inmsgtype, transition) if operation.getText() == self.tMODSTATEFUNC: return self._gen_mod_state_func(operation, arch) + self.end if operation.getChildren()[0].getText() == self.iState: return self._genArchAccess(transition) if operation.getText() == self.tSEND: return self._genSendFunction(operation) + self.end if operation.getText() == self.tMCAST: return self._genMCastFunction(operation) + self.end if operation.getText() == self.tBCAST: return self._genBCastFunction(operation) + self.end # For every if cond=true, there exists an else (if cond=false) if operation.getText() == self.tCOND: return self._genIfCondFunction(operation, 0, arch, inmsgtype) + self.nl if operation.getText() == self.tNCOND: return self._genIfCondFunction(operation, 1, arch, inmsgtype) + self.nl if operation.getText() == self.tSETFUNC: return self._genSetFunction(operation, arch, inmsgtype) + self.end # DEFER FUNCTION FUNCTIONALITY if operation.getText() == self.tPUSH_HL_DEFER: msg_name = str(operation.children[1]) if msg_name in self.messageslist: msg_name = self.cinmsg return self._genmsgDeferpush(arch, msg_name, MurphiTokens.iHL_Defer) if operation.getText() == self.tPUSH_LL_DEFER: msg_name = str(operation.children[1]) if msg_name in self.messageslist: msg_name = self.cinmsg return self._genmsgDeferpush(arch, msg_name, MurphiTokens.iLL_Defer) if operation.getText() == self.tPUSH_STALL_DEFER: msg_name = str(operation.children[1]) if msg_name in self.messageslist: msg_name = self.cinmsg return self._genmsgDeferpush(arch, msg_name, MurphiTokens.iStall_Defer)
def test_serialization_msg(self, transition: Transition) -> bool: # Rule if a remote transition exists in the stable startstate and stable finalstate having the same guard, # the message is considered NOT to be a serialization message and therefore to be unrelated to the current state # and will be therefore ignored until a stable state is reached if the ProtoGen works in the stalling mode or # handled if no data dependencies exist in the non-stalling mode guard = str(transition.getguard()) if (self.state_guard_search(guard, transition.startState) and self.state_guard_search(guard, transition.finalState)): return False return True
def send_base_message(self, trans_operation: CommonTree, transition: Transition, var_names: Dict[str, str]) -> List[CommonTree]: ret_operation = trans_operation children = trans_operation.getChildren() if str(children[1]) in var_names: tmp_operation = copy.deepcopy(trans_operation) tmp_operation.token.text = MurphiModular.tPUSH_HL_DEFER tmp_operation.children[1].token.text = var_names[str(children[1])] transition.operation = copy.copy(transition.operation) transition.operation[transition.operation.index( trans_operation)] = tmp_operation return [ret_operation] return []
def defer_base_message(self, trans_operation: CommonTree, transition: Transition, var_names: Dict[str, str]) -> List[CommonTree]: local_defer_operations = [] children = trans_operation.getChildren() defer_var_name = MurphiModular.vdeferpref + str(children[0]) + "_" + \ str(children[2].children[1]) # Records the variable name of the child var_names[str(children[0])] = defer_var_name # Recover next deferred operation tmp_operation = copy.deepcopy(trans_operation) tmp_children = tmp_operation.getChildren() defer_var_name = MurphiModular.vdeferpref + str(tmp_children[0]) + "_" + \ str(tmp_children[2].children[1]) tmp_children[0].token.text = defer_var_name tmp_children[2].token.text = MurphiModular.tPOP_HL_DEFER local_defer_operations.append(tmp_operation) # Construct Original Message from deferred operation tmp_operation = copy.deepcopy(trans_operation) tmp_children = tmp_operation.getChildren() tmp_children[2].token.text = MurphiModular.tSEND_BASE_DEFER tmp_children[2].children[1].token.text = defer_var_name for ind in range(2, len(MurphiModular.BaseMsg)): tmp_children[2].children.pop(2) local_defer_operations.append(tmp_operation) tmp_operation = copy.deepcopy(trans_operation) tmp_children = tmp_operation.getChildren() # Generate BaseMessage that is deferred tmp_children[0].token.text = defer_var_name tmp_children[2].token.text = MurphiModular.tSEND_BASE_DEFER tmp_children[2].children[0].token.text = MurphiModular.rbasemessage for ind in range(len(MurphiModular.BaseMsg), len(tmp_children[2].getChildren())): tmp_children[2].children.pop(len(MurphiModular.BaseMsg)) # Update the transition transition.operation = copy.copy(transition.operation) transition.operation[transition.operation.index( trans_operation)] = tmp_operation return local_defer_operations
def __init__(self, startstate, guard, finalstate): assert isinstance(startstate, StateNode) assert isinstance(finalstate, StateNode) assert isinstance(guard, str) self.messages = {} self.trans = [] self.startState = startstate self.interfinalState = finalstate.getstatename() self.access = guard self.TransTree = ForkTree() self.ifTree = 0 self.TransTree.insertnode(Transition(startstate, finalstate, guard)) self.IfTree = ForkTree()
def rename_final_state_add_dir(self, rename_state_list: Dict[State, State], cc_transition: Transition, dir_state: State, prefix=""): if isinstance(cc_transition.finalState, list): start_state = cc_transition.finalState[0] else: start_state = cc_transition.finalState cc_state_str = prefix + self.new_state_name(dir_state.state, start_state.state) cc_transition.finalState = self.cc_dir_state(rename_state_list, cc_state_str, start_state) if isinstance(cc_transition.finalState, list): for start_state in cc_transition.finalState: self.add_to_dict_list(self.cc_dir_to_cc_state_map, cc_transition.finalState, start_state) else: self.add_to_dict_list(self.cc_dir_to_cc_state_map, cc_transition.finalState, start_state)
def rename_start_state_add_cc(self, rename_state_list: Dict[State, State], cc_state: State, dir_transition: Transition, prefix=""): if isinstance(dir_transition.startState, list): start_state = dir_transition.startState[0] else: start_state = dir_transition.startState dir_state_str = prefix + self.new_state_name(start_state.state, cc_state.state) dir_transition.startState = self.cc_dir_state(rename_state_list, dir_state_str, start_state) if isinstance(dir_transition.startState, list): for start_state in dir_transition.startState: self.add_to_dict_list(self.cc_dir_to_dir_state_map, dir_transition.startState, start_state) else: self.add_to_dict_list(self.cc_dir_to_dir_state_map, dir_transition.startState, start_state)
def copy_modify_state(self, startstate: State, transition: Transition, old_state_to_new_state_map: Dict[str, State], forbidden_guards: List[str], final_state: [State, None] = None): # If a known final state exists, then if final_state: newstate = final_state if str(final_state) in old_state_to_new_state_map: newstate = old_state_to_new_state_map[str(final_state)] else: new_state_str = startstate.getstatename( ) + "_" + transition.getguard() if new_state_str in old_state_to_new_state_map: newstate = old_state_to_new_state_map[new_state_str] else: newstate = State(new_state_str, self.access, self.evict) old_state_to_new_state_map[new_state_str] = newstate # The new_state replaces the final state so it must possess all local access permissions for trans in transition.startState.setTrans: if str(trans.inMsg) in forbidden_guards: continue if trans.startState == trans.finalState: new_trans = self._CopyModifyTransition( trans, newstate, newstate) newstate.addtransitions(new_trans) for trans in transition.finalState.setTrans: if str(trans.inMsg) in forbidden_guards: continue if trans.startState == trans.finalState: new_trans = self._CopyModifyTransition( trans, newstate, newstate) newstate.addtransitions(new_trans) # The new_state replaces the final state so it must possess all local access permissions for trans in startstate.setTrans: if str(trans.inMsg) in forbidden_guards: continue if trans.startState == trans.finalState: new_trans = self._CopyModifyTransition( trans, newstate, newstate) newstate.addtransitions(new_trans) for startset in transition.getfinalstate().getstatesets(): startset.addstartstate(newstate) for endset in startstate.getendstatesets(): endset.addendstate(newstate) # Create vertice new_trans = self._CopyModifyTransition(transition, startstate, newstate) startstate.addtransitions(new_trans) return newstate, new_trans
def _TransientStateInheritance(self, arch: Architecture, transition: Transition, state, stateset, stablestates, deferfunc) -> List[State]: new_states = [] # Test if the message is a serialization message or any other control message # In the non-stalling configuration control messages are deferred if control dependencies exist, # else they are served immediately if not self.nonstalling: if not self.test_serialization_msg(transition): return new_states finalsets = transition.getfinalstate().getstatesets() # Rule if a remote transition exists in the startstate and finalstate having the same guard, the message # is considered to be unrelated to the current state and will be therefore ignored until a stable state is # reached # Test if final stable state or remote transition is startstate of current stateset if state in stateset.getstartstates(): # Serialized before own transaction # Find path startstate to state guards = self._FindAccessTrace(state, stateset, stablestates) # Find new final state finalstate = self._SetGuardSearch(guards, finalsets) if finalstate: state.addtransitions( self._CopyModifyTransition(transition, state, finalstate)) else: new_states.append(self._CopyModifyState(state, transition)) else: # Serialized after own transaction if self.nonstalling: # Cache and directory dependent. Only if they have data # Transition start and final state do not change, however, # responses might be deferred due to data dependencies if transition.getstartstate() == transition.getfinalstate( ) and state in stateset.getendstates(): pass # ANALYZE DEPENDENCY OF CURRENT TRANSITION AND VARIABLES THAT ARE DEPENDENT. # IF THERE EXISTS A DEPENDENCY NO LOOPING IS ALLOWED ''' newtrans = self._CopyModifyTransition(transition, state, state) # Defer message defermsg = deferfunc(transition, newtrans) if defermsg: new_state = self._GenerateState(state, transition, stablestates, deferfunc) if new_state: new_states.append(new_state) else: state.addtransitions(newtrans) ''' else: # A new state needs to be created new_state = self._GenerateState(state, transition, stablestates, deferfunc) if new_state: new_states.append(new_state) return new_states
def _genFinalState(self, arch: str, transition: Transition): return self.ccle + "." + self.iState + " := " + arch + "_" + \ transition.getfinalstate().getstatename() + self.end
def newwhen(self, startstate, finalstate, guard, prenode): return self.TransTree.insertnode( Transition(startstate, finalstate, guard), prenode)
def dummy_trace(self, state: State): trans = Transition(state, state) return Trace.constr_trace_from_trans(trans)