1# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 2# Copyright (c) 2009 The Hewlett-Packard Development Company 3# All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions are 7# met: redistributions of source code must retain the above copyright 8# notice, this list of conditions and the following disclaimer; --- 32 unchanged lines hidden (view full) --- 41 "DMASequencer": "DMASequencer" 42 } 43 44class StateMachine(Symbol): 45 def __init__(self, symtab, ident, location, pairs, config_parameters): 46 super(StateMachine, self).__init__(symtab, ident, location, pairs) 47 self.table = None 48 self.config_parameters = config_parameters |
49 |
50 for param in config_parameters: 51 if param.pointer: 52 var = Var(symtab, param.name, location, param.type_ast.type, 53 "(*m_%s_ptr)" % param.name, {}, self) 54 else: 55 var = Var(symtab, param.name, location, param.type_ast.type, 56 "m_%s" % param.name, {}, self) 57 self.symtab.registerSym(param.name, var) 58 59 self.states = orderdict() 60 self.events = orderdict() 61 self.actions = orderdict() 62 self.transitions = [] 63 self.in_ports = [] 64 self.functions = [] 65 self.objects = [] |
66 self.TBEType = None 67 self.EntryType = None |
68 69 self.message_buffer_names = [] 70 71 def __repr__(self): 72 return "[StateMachine: %s]" % self.ident 73 74 def addState(self, state): 75 assert self.table is None --- 29 unchanged lines hidden (view full) --- 105 def addFunc(self, func): 106 # register func in the symbol table 107 self.symtab.registerSym(str(func), func) 108 self.functions.append(func) 109 110 def addObject(self, obj): 111 self.objects.append(obj) 112 |
113 def addType(self, type): 114 type_ident = '%s' % type.c_ident 115 116 if type_ident == "%s_TBE" %self.ident: 117 if self.TBEType != None: 118 self.error("Multiple Transaction Buffer types in a " \ 119 "single machine."); 120 self.TBEType = type 121 122 elif "interface" in type and "AbstractCacheEntry" == type["interface"]: 123 if self.EntryType != None: 124 self.error("Multiple AbstractCacheEntry types in a " \ 125 "single machine."); 126 self.EntryType = type 127 |
128 # Needs to be called before accessing the table 129 def buildTable(self): 130 assert self.table is None 131 132 table = {} 133 134 for trans in self.transitions: 135 # Track which actions we touch so we know if we use them --- 141 unchanged lines hidden (view full) --- 277 code('${{param.type_ast.type}}* m_${{param.ident}}_ptr;') 278 else: 279 code('${{param.type_ast.type}} m_${{param.ident}};') 280 281 code(''' 282int m_number_of_TBEs; 283 284TransitionResult doTransition(${ident}_Event event, |
285''') 286 287 if self.EntryType != None: 288 code(''' 289 ${{self.EntryType.c_ident}}* m_cache_entry_ptr, 290''') 291 if self.TBEType != None: 292 code(''' 293 ${{self.TBEType.c_ident}}* m_tbe_ptr, 294''') 295 296 code(''' |
297 const Address& addr); 298 299TransitionResult doTransitionWorker(${ident}_Event event, 300 ${ident}_State state, 301 ${ident}_State& next_state, |
302''') 303 304 if self.TBEType != None: 305 code(''' 306 ${{self.TBEType.c_ident}}*& m_tbe_ptr, 307''') 308 if self.EntryType != None: 309 code(''' 310 ${{self.EntryType.c_ident}}*& m_cache_entry_ptr, 311''') 312 313 code(''' |
314 const Address& addr); 315 316std::string m_name; 317int m_transitions_per_cycle; 318int m_buffer_size; 319int m_recycle_latency; 320std::map<std::string, std::string> m_cfg; 321NodeID m_version; --- 13 unchanged lines hidden (view full) --- 335// Internal functions 336''') 337 338 for func in self.functions: 339 proto = func.prototype 340 if proto: 341 code('$proto') 342 |
343 if self.EntryType != None: 344 code(''' 345 346// Set and Reset for cache_entry variable 347void set_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr, AbstractCacheEntry* m_new_cache_entry); 348void unset_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr); 349''') 350 351 if self.TBEType != None: 352 code(''' 353 354// Set and Reset for tbe variable 355void set_tbe(${{self.TBEType.c_ident}}*& m_tbe_ptr, ${ident}_TBE* m_new_tbe); 356void unset_tbe(${{self.TBEType.c_ident}}*& m_tbe_ptr); 357''') 358 |
359 code(''' 360 361// Actions 362''') |
363 if self.TBEType != None and self.EntryType != None: 364 for action in self.actions.itervalues(): 365 code('/** \\brief ${{action.desc}} */') 366 code('void ${{action.ident}}(${{self.TBEType.c_ident}}*& m_tbe_ptr, ${{self.EntryType.c_ident}}*& m_cache_entry_ptr, const Address& addr);') 367 elif self.TBEType != None: 368 for action in self.actions.itervalues(): 369 code('/** \\brief ${{action.desc}} */') 370 code('void ${{action.ident}}(${{self.TBEType.c_ident}}*& m_tbe_ptr, const Address& addr);') 371 elif self.EntryType != None: 372 for action in self.actions.itervalues(): 373 code('/** \\brief ${{action.desc}} */') 374 code('void ${{action.ident}}(${{self.EntryType.c_ident}}*& m_cache_entry_ptr, const Address& addr);') 375 else: 376 for action in self.actions.itervalues(): 377 code('/** \\brief ${{action.desc}} */') 378 code('void ${{action.ident}}(const Address& addr);') |
379 380 # the controller internal variables 381 code(''' 382 383// Objects 384''') 385 for var in self.objects: 386 th = var.get("template_hack", "") --- 409 unchanged lines hidden (view full) --- 796 if param.type_ast.type.ident == "CacheMemory" or \ 797 param.type_ast.type.ident == "MemoryControl": 798 assert(param.pointer) 799 code(' m_${{param.ident}}_ptr->clearStats();') 800 801 code(''' 802 m_profiler.clearStats(); 803} |
804''') |
805 |
806 if self.EntryType != None: 807 code(''' 808 809// Set and Reset for cache_entry variable 810void 811$c_ident::set_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr, AbstractCacheEntry* m_new_cache_entry) 812{ 813 m_cache_entry_ptr = (${{self.EntryType.c_ident}}*)m_new_cache_entry; 814} 815 816void 817$c_ident::unset_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr) 818{ 819 m_cache_entry_ptr = 0; 820} 821''') 822 823 if self.TBEType != None: 824 code(''' 825 826// Set and Reset for tbe variable 827void 828$c_ident::set_tbe(${{self.TBEType.c_ident}}*& m_tbe_ptr, ${{self.TBEType.c_ident}}* m_new_tbe) 829{ 830 m_tbe_ptr = m_new_tbe; 831} 832 833void 834$c_ident::unset_tbe(${{self.TBEType.c_ident}}*& m_tbe_ptr) 835{ 836 m_tbe_ptr = NULL; 837} 838''') 839 840 code(''' 841 |
842// Actions 843''') |
844 if self.TBEType != None and self.EntryType != None: 845 for action in self.actions.itervalues(): 846 if "c_code" not in action: 847 continue |
848 |
849 code(''' 850/** \\brief ${{action.desc}} */ 851void 852$c_ident::${{action.ident}}(${{self.TBEType.c_ident}}*& m_tbe_ptr, ${{self.EntryType.c_ident}}*& m_cache_entry_ptr, const Address& addr) 853{ 854 DPRINTF(RubyGenerated, "executing\\n"); 855 ${{action["c_code"]}} 856} |
857 |
858''') 859 elif self.TBEType != None: 860 for action in self.actions.itervalues(): 861 if "c_code" not in action: 862 continue 863 864 code(''' |
865/** \\brief ${{action.desc}} */ 866void |
867$c_ident::${{action.ident}}(${{self.TBEType.c_ident}}*& m_tbe_ptr, const Address& addr) 868{ 869 DPRINTF(RubyGenerated, "executing\\n"); 870 ${{action["c_code"]}} 871} 872 873''') 874 elif self.EntryType != None: 875 for action in self.actions.itervalues(): 876 if "c_code" not in action: 877 continue 878 879 code(''' 880/** \\brief ${{action.desc}} */ 881void 882$c_ident::${{action.ident}}(${{self.EntryType.c_ident}}*& m_cache_entry_ptr, const Address& addr) 883{ 884 DPRINTF(RubyGenerated, "executing\\n"); 885 ${{action["c_code"]}} 886} 887 888''') 889 else: 890 for action in self.actions.itervalues(): 891 if "c_code" not in action: 892 continue 893 894 code(''' 895/** \\brief ${{action.desc}} */ 896void |
897$c_ident::${{action.ident}}(const Address& addr) 898{ 899 DPRINTF(RubyGenerated, "executing\\n"); 900 ${{action["c_code"]}} 901} 902 903''') 904 code.write(path, "%s.cc" % c_ident) --- 19 unchanged lines hidden (view full) --- 924#include "mem/protocol/Types.hh" 925#include "mem/ruby/system/System.hh" 926 927using namespace std; 928 929void 930${ident}_Controller::wakeup() 931{ |
932 int counter = 0; 933 while (true) { 934 // Some cases will put us into an infinite loop without this limit 935 assert(counter <= m_transitions_per_cycle); 936 if (counter == m_transitions_per_cycle) { 937 // Count how often we are fully utilized 938 g_system_ptr->getProfiler()->controllerBusy(m_machineID); 939 --- 54 unchanged lines hidden (view full) --- 994 995#define HASH_FUN(state, event) ((int(state)*${ident}_Event_NUM)+int(event)) 996 997#define GET_TRANSITION_COMMENT() (${ident}_transitionComment.str()) 998#define CLEAR_TRANSITION_COMMENT() (${ident}_transitionComment.str("")) 999 1000TransitionResult 1001${ident}_Controller::doTransition(${ident}_Event event, |
1002''') 1003 if self.EntryType != None: 1004 code(''' 1005 ${{self.EntryType.c_ident}}* m_cache_entry_ptr, 1006''') 1007 if self.TBEType != None: 1008 code(''' 1009 ${{self.TBEType.c_ident}}* m_tbe_ptr, 1010''') 1011 code(''' |
1012 const Address &addr) 1013{ |
1014''') 1015 if self.TBEType != None and self.EntryType != None: 1016 code('${ident}_State state = ${ident}_getState(m_tbe_ptr, m_cache_entry_ptr, addr);') 1017 elif self.TBEType != None: 1018 code('${ident}_State state = ${ident}_getState(m_tbe_ptr, addr);') 1019 elif self.EntryType != None: 1020 code('${ident}_State state = ${ident}_getState(m_cache_entry_ptr, addr);') 1021 else: 1022 code('${ident}_State state = ${ident}_getState(addr);') 1023 1024 code(''' |
1025 ${ident}_State next_state = state; 1026 1027 DPRINTF(RubyGenerated, "%s, Time: %lld, state: %s, event: %s, addr: %s\\n", 1028 *this, 1029 g_eventQueue_ptr->getTime(), 1030 ${ident}_State_to_string(state), 1031 ${ident}_Event_to_string(event), 1032 addr); 1033 1034 TransitionResult result = |
1035''') 1036 if self.TBEType != None and self.EntryType != None: 1037 code('doTransitionWorker(event, state, next_state, m_tbe_ptr, m_cache_entry_ptr, addr);') 1038 elif self.TBEType != None: 1039 code('doTransitionWorker(event, state, next_state, m_tbe_ptr, addr);') 1040 elif self.EntryType != None: 1041 code('doTransitionWorker(event, state, next_state, m_cache_entry_ptr, addr);') 1042 else: 1043 code('doTransitionWorker(event, state, next_state, addr);') |
1044 |
1045 code(''' |
1046 if (result == TransitionResult_Valid) { 1047 DPRINTF(RubyGenerated, "next_state: %s\\n", 1048 ${ident}_State_to_string(next_state)); 1049 m_profiler.countTransition(state, event); 1050 DPRINTFR(ProtocolTrace, "%7d %3s %10s%20s %6s>%-6s %s %s\\n", 1051 g_eventQueue_ptr->getTime(), m_version, "${ident}", 1052 ${ident}_Event_to_string(event), 1053 ${ident}_State_to_string(state), 1054 ${ident}_State_to_string(next_state), 1055 addr, GET_TRANSITION_COMMENT()); 1056 1057 CLEAR_TRANSITION_COMMENT(); |
1058''') 1059 if self.TBEType != None and self.EntryType != None: 1060 code('${ident}_setState(m_tbe_ptr, m_cache_entry_ptr, addr, next_state);') 1061 elif self.TBEType != None: 1062 code('${ident}_setState(m_tbe_ptr, addr, next_state);') 1063 elif self.EntryType != None: 1064 code('${ident}_setState(m_cache_entry_ptr, addr, next_state);') 1065 else: 1066 code('${ident}_setState(addr, next_state);') 1067 1068 code(''' |
1069 } else if (result == TransitionResult_ResourceStall) { 1070 DPRINTFR(ProtocolTrace, "%7s %3s %10s%20s %6s>%-6s %s %s\\n", 1071 g_eventQueue_ptr->getTime(), m_version, "${ident}", 1072 ${ident}_Event_to_string(event), 1073 ${ident}_State_to_string(state), 1074 ${ident}_State_to_string(next_state), 1075 addr, "Resource Stall"); 1076 } else if (result == TransitionResult_ProtocolStall) { --- 8 unchanged lines hidden (view full) --- 1085 1086 return result; 1087} 1088 1089TransitionResult 1090${ident}_Controller::doTransitionWorker(${ident}_Event event, 1091 ${ident}_State state, 1092 ${ident}_State& next_state, |
1093''') 1094 1095 if self.TBEType != None: 1096 code(''' 1097 ${{self.TBEType.c_ident}}*& m_tbe_ptr, 1098''') 1099 if self.EntryType != None: 1100 code(''' 1101 ${{self.EntryType.c_ident}}*& m_cache_entry_ptr, 1102''') 1103 code(''' |
1104 const Address& addr) 1105{ 1106 switch(HASH_FUN(state, event)) { 1107''') 1108 1109 # This map will allow suppress generating duplicate code 1110 cases = orderdict() 1111 --- 32 unchanged lines hidden (view full) --- 1144 for action in actions: 1145 if action.ident == "z_stall": 1146 stall = True 1147 break 1148 1149 if stall: 1150 case('return TransitionResult_ProtocolStall;') 1151 else: |
1152 if self.TBEType != None and self.EntryType != None: 1153 for action in actions: 1154 case('${{action.ident}}(m_tbe_ptr, m_cache_entry_ptr, addr);') 1155 elif self.TBEType != None: 1156 for action in actions: 1157 case('${{action.ident}}(m_tbe_ptr, addr);') 1158 elif self.EntryType != None: 1159 for action in actions: 1160 case('${{action.ident}}(m_cache_entry_ptr, addr);') 1161 else: 1162 for action in actions: 1163 case('${{action.ident}}(addr);') |
1164 case('return TransitionResult_Valid;') 1165 1166 case = str(case) 1167 1168 # Look to see if this transition code is unique. 1169 if case not in cases: 1170 cases[case] = [] 1171 --- 419 unchanged lines hidden --- |