diff --git a/generator/transform/GeneratePML.py b/generator/transform/GeneratePML.py index 010224716e295a720c48f637eacea3d34cbe62d0..ecb5dfdad34fff12457025778567d3dd0964dd1f 100644 --- a/generator/transform/GeneratePML.py +++ b/generator/transform/GeneratePML.py @@ -30,40 +30,47 @@ class GeneratePML(Analysis): start_states.append(state) if state.current_abb in end: end_states.append(state) - #if state.current_abb in stop: - # stop_states.append(state) start_state_ids = {id(x) for x in start_states} end_state_ids = {id(x) for x in end_states} # stop_state_ids = {id(x) for x in stop_states} # 2. DFS starting from the first element in the graph. # 2.1 All end states are definitly part of the graph - good_states = { id(x): x for x in end_states } + good_states = { } def dfs(path, curr): + # Uncomment for debugging purposes + # print("V", [(x.current_subtask, x.current_abb) for x in path + [curr]]) + + if id(curr) in end_state_ids or id(curr) in good_states or\ + id(curr) in [id(x) for x in path]: + # print("A") + # Add the path to the good states + for x in path + [curr]: + good_states[id(x)] = x + + # Stop DFS, if we were here already if id(curr) in visited: return - # Uncomment for debugging purposes - #print("V", [x.current_abb for x in path]) - if id(curr) in good_states: - for x in path: - if id(x) not in good_states: - stack.append(x) - good_states[id(x)] = x - return True visited.add(id(curr)) path = path + [curr] for succ in curr.get_outgoing_nodes(SavedStateTransition): - if dfs(path, succ): - return True + # Do not proceed locally on state graph within subtask + if id(curr) in end_state_ids: + if succ.current_subtask == curr.current_subtask: + continue + dfs(path, succ) - stack = list(start_states) + list(end_states) - while stack: - state = stack.pop() - for succ in state.get_outgoing_nodes(SavedStateTransition): - visited = set() - dfs([state], succ) + visited = set() + for state in start_states: + dfs([], state) + + # for state in good_states.values(): + # print(state.current_abb) + for state in good_states.values(): + if state.current_abb.isA(S.Idle): + logging.warning("Idle state part of circuit... unanalyzable") # Every State can only occur only once in the result return good_states.values() @@ -199,9 +206,11 @@ class GeneratePML(Analysis): if state.current_abb in abb_to_idx: data['abb'] = abb_to_idx[state.current_abb] data['abb-name'] = str(state.current_abb) - if state.current_abb.isA(S.Idle): + elif state.current_abb.isA(S.Idle): data['abb-name'] = "Idle" data['cost'] = 0 + else: + data['abb-name'] = str(state.current_abb) + " WEIRDO" gcfg['nodes'].append(data) @@ -213,12 +222,10 @@ class GeneratePML(Analysis): for region in self.find_irq_regions(circuit): isr_entry = region['entry'] isr_entry_data = gcfg['nodes'][idx(isr_entry)] + # Sometimes an IRQ entry can be + if region['entry'].current_abb in circuit['start']: + gcfg['entry-nodes'].append(idx(isr_entry)) - interrupted = isr_entry.definite_before(SavedStateTransition) - interrupted_data = gcfg['nodes'][idx(interrupted)] - - handler = isr_entry.definite_after(SavedStateTransition) - handler_data = gcfg['nodes'][idx(handler)] # Give the isr_entry block a flow variable. This flow # variable, will capture how often an interrupt is @@ -303,6 +310,7 @@ class GeneratePML(Analysis): 'origin': 'user.bc', 'classification': 'system-global', }) + logging.info(" %s triggers every %d-nth time", alarm.conf.name, cycletime) # The number of AST Reschedule events is the number actcual # ast_reschedule requests @@ -336,6 +344,7 @@ class GeneratePML(Analysis): kickoff = self.system_graph.idle_subtask.entry_abb for abb in idle.abbs: kickoff.call_sites.extend(abb.call_sites) + abb.call_sites = [] # We search for all circuits, the user has annotated with # function calls in his application @@ -343,14 +352,19 @@ class GeneratePML(Analysis): for abb in self.system_graph.abbs: for (bb, func, circuit) in abb.call_sites: if func == "timing_start": - circuits[circuit[0]]["start"].append(abb) + if abb.subtask.conf.is_isr: + logging.info(" timing-%d starts with IRQ activation", circuit[0]) + before = abb.definite_before(E.function_level) + assert before.isA(S.kickoff), "Can start analysis only at beginning of ISR" + circuits[circuit[0]]["start"].append(before) + else: + circuits[circuit[0]]["start"].append(abb) if func == "timing_end": circuits[circuit[0]]["end"].append(abb) # Finds all states in between for circuit, data in circuits.items(): states = self.get_circuit_states(data["start"], data["end"]) - data['states'] = states data['circuit'] = circuit # Copy ID into dict data['state-ids'] = {id(x) for x in data['states']}