StateMachine.py (7832:de7601e6e19d) StateMachine.py (7839:9e556fb25900)
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
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
49 for param in config_parameters:
50 if param.pointer:
51 var = Var(symtab, param.name, location, param.type_ast.type,
52 "(*m_%s_ptr)" % param.name, {}, self)
53 else:
54 var = Var(symtab, param.name, location, param.type_ast.type,
55 "m_%s" % param.name, {}, self)
56 self.symtab.registerSym(param.name, var)
57
58 self.states = orderdict()
59 self.events = orderdict()
60 self.actions = orderdict()
61 self.transitions = []
62 self.in_ports = []
63 self.functions = []
64 self.objects = []
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
65
66 self.message_buffer_names = []
67
68 def __repr__(self):
69 return "[StateMachine: %s]" % self.ident
70
71 def addState(self, state):
72 assert self.table is None

--- 29 unchanged lines hidden (view full) ---

102 def addFunc(self, func):
103 # register func in the symbol table
104 self.symtab.registerSym(str(func), func)
105 self.functions.append(func)
106
107 def addObject(self, obj):
108 self.objects.append(obj)
109
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
110 # Needs to be called before accessing the table
111 def buildTable(self):
112 assert self.table is None
113
114 table = {}
115
116 for trans in self.transitions:
117 # Track which actions we touch so we know if we use them

--- 141 unchanged lines hidden (view full) ---

259 code('${{param.type_ast.type}}* m_${{param.ident}}_ptr;')
260 else:
261 code('${{param.type_ast.type}} m_${{param.ident}};')
262
263 code('''
264int m_number_of_TBEs;
265
266TransitionResult doTransition(${ident}_Event event,
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,
267 ${ident}_State state,
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('''
268 const Address& addr);
269
270TransitionResult doTransitionWorker(${ident}_Event event,
271 ${ident}_State state,
272 ${ident}_State& next_state,
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('''
273 const Address& addr);
274
275std::string m_name;
276int m_transitions_per_cycle;
277int m_buffer_size;
278int m_recycle_latency;
279std::map<std::string, std::string> m_cfg;
280NodeID m_version;

--- 13 unchanged lines hidden (view full) ---

294// Internal functions
295''')
296
297 for func in self.functions:
298 proto = func.prototype
299 if proto:
300 code('$proto')
301
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
302 code('''
303
304// Actions
305''')
359 code('''
360
361// Actions
362''')
306 for action in self.actions.itervalues():
307 code('/** \\brief ${{action.desc}} */')
308 code('void ${{action.ident}}(const Address& addr);')
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);')
309
310 # the controller internal variables
311 code('''
312
313// Objects
314''')
315 for var in self.objects:
316 th = var.get("template_hack", "")

--- 409 unchanged lines hidden (view full) ---

726 if param.type_ast.type.ident == "CacheMemory" or \
727 param.type_ast.type.ident == "MemoryControl":
728 assert(param.pointer)
729 code(' m_${{param.ident}}_ptr->clearStats();')
730
731 code('''
732 m_profiler.clearStats();
733}
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''')
734
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
735// Actions
736''')
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
737
848
738 for action in self.actions.itervalues():
739 if "c_code" not in action:
740 continue
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}
741
857
742 code('''
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('''
743/** \\brief ${{action.desc}} */
744void
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
745$c_ident::${{action.ident}}(const Address& addr)
746{
747 DPRINTF(RubyGenerated, "executing\\n");
748 ${{action["c_code"]}}
749}
750
751''')
752 code.write(path, "%s.cc" % c_ident)

--- 19 unchanged lines hidden (view full) ---

772#include "mem/protocol/Types.hh"
773#include "mem/ruby/system/System.hh"
774
775using namespace std;
776
777void
778${ident}_Controller::wakeup()
779{
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{
780 // DEBUG_EXPR(GENERATED_COMP, MedPrio, *this);
781 // DEBUG_EXPR(GENERATED_COMP, MedPrio, g_eventQueue_ptr->getTime());
782
783 int counter = 0;
784 while (true) {
785 // Some cases will put us into an infinite loop without this limit
786 assert(counter <= m_transitions_per_cycle);
787 if (counter == m_transitions_per_cycle) {
788 // Count how often we are fully utilized
789 g_system_ptr->getProfiler()->controllerBusy(m_machineID);
790

--- 54 unchanged lines hidden (view full) ---

845
846#define HASH_FUN(state, event) ((int(state)*${ident}_Event_NUM)+int(event))
847
848#define GET_TRANSITION_COMMENT() (${ident}_transitionComment.str())
849#define CLEAR_TRANSITION_COMMENT() (${ident}_transitionComment.str(""))
850
851TransitionResult
852${ident}_Controller::doTransition(${ident}_Event event,
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,
853 ${ident}_State state,
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('''
854 const Address &addr)
855{
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('''
856 ${ident}_State next_state = state;
857
858 DPRINTF(RubyGenerated, "%s, Time: %lld, state: %s, event: %s, addr: %s\\n",
859 *this,
860 g_eventQueue_ptr->getTime(),
861 ${ident}_State_to_string(state),
862 ${ident}_Event_to_string(event),
863 addr);
864
865 TransitionResult result =
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 =
866 doTransitionWorker(event, state, next_state, addr);
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);')
867
1044
1045 code('''
868 if (result == TransitionResult_Valid) {
869 DPRINTF(RubyGenerated, "next_state: %s\\n",
870 ${ident}_State_to_string(next_state));
871 m_profiler.countTransition(state, event);
872 DPRINTFR(ProtocolTrace, "%7d %3s %10s%20s %6s>%-6s %s %s\\n",
873 g_eventQueue_ptr->getTime(), m_version, "${ident}",
874 ${ident}_Event_to_string(event),
875 ${ident}_State_to_string(state),
876 ${ident}_State_to_string(next_state),
877 addr, GET_TRANSITION_COMMENT());
878
879 CLEAR_TRANSITION_COMMENT();
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();
880 ${ident}_setState(addr, next_state);
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('''
881 } else if (result == TransitionResult_ResourceStall) {
882 DPRINTFR(ProtocolTrace, "%7s %3s %10s%20s %6s>%-6s %s %s\\n",
883 g_eventQueue_ptr->getTime(), m_version, "${ident}",
884 ${ident}_Event_to_string(event),
885 ${ident}_State_to_string(state),
886 ${ident}_State_to_string(next_state),
887 addr, "Resource Stall");
888 } else if (result == TransitionResult_ProtocolStall) {

--- 8 unchanged lines hidden (view full) ---

897
898 return result;
899}
900
901TransitionResult
902${ident}_Controller::doTransitionWorker(${ident}_Event event,
903 ${ident}_State state,
904 ${ident}_State& next_state,
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('''
905 const Address& addr)
906{
907 switch(HASH_FUN(state, event)) {
908''')
909
910 # This map will allow suppress generating duplicate code
911 cases = orderdict()
912

--- 32 unchanged lines hidden (view full) ---

945 for action in actions:
946 if action.ident == "z_stall":
947 stall = True
948 break
949
950 if stall:
951 case('return TransitionResult_ProtocolStall;')
952 else:
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:
953 for action in actions:
954 case('${{action.ident}}(addr);')
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);')
955 case('return TransitionResult_Valid;')
956
957 case = str(case)
958
959 # Look to see if this transition code is unique.
960 if case not in cases:
961 cases[case] = []
962

--- 419 unchanged lines hidden ---
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 ---