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;

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

174 for action in self.actions.itervalues():
175 if not action.used:
176 error_msg = "Unused action: %s" % action.ident
177 if "desc" in action:
178 error_msg += ", " + action.desc
179 action.warning(error_msg)
180 self.table = table
181
182 # determine the port->msg buffer mappings
183 def getBufferMaps(self, ident):
184 msg_bufs = []
185 port_to_buf_map = {}
186 in_msg_bufs = {}
187 for port in self.in_ports:
188 buf_name = "m_%s_ptr" % port.buffer_expr.name
189 msg_bufs.append(buf_name)
190 port_to_buf_map[port] = msg_bufs.index(buf_name)
191 if buf_name not in in_msg_bufs:
192 in_msg_bufs[buf_name] = [port]
193 else:
194 in_msg_bufs[buf_name].append(port)
195 return port_to_buf_map, in_msg_bufs, msg_bufs
196
197 def writeCodeFiles(self, path, includes):
198 self.printControllerPython(path)
199 self.printControllerHH(path)
200 self.printControllerCC(path, includes)
201 self.printCSwitch(path)
202 self.printCWakeup(path, includes)
203
204 def printControllerPython(self, path):

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

433 code('''
434/** \\file $c_ident.cc
435 *
436 * Auto generated C++ code started by $__file__:$__line__
437 * Created by slicc definition of Module "${{self.short}}"
438 */
439
440#include <sys/types.h>
441#include <typeinfo>
442#include <unistd.h>
443
444#include <cassert>
445#include <sstream>
446#include <string>
447
448#include "base/compiler.hh"
449#include "base/cprintf.hh"

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

946 continue
947
948 code('''
949/** \\brief ${{action.desc}} */
950void
951$c_ident::${{action.ident}}(${{self.TBEType.c_ident}}*& m_tbe_ptr, ${{self.EntryType.c_ident}}*& m_cache_entry_ptr, const Address& addr)
952{
953 DPRINTF(RubyGenerated, "executing ${{action.ident}}\\n");
938 ${{action["c_code"]}}
954 try {
955 ${{action["c_code"]}}
956 } catch (const RejectException & e) {
957 fatal("Error in action ${{ident}}:${{action.ident}}: "
958 "executed a peek statement with the wrong message "
959 "type specified. ");
960 }
961}
962
963''')
964 elif self.TBEType != None:
965 for action in self.actions.itervalues():
966 if "c_code" not in action:
967 continue
968

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

1045 if len(self.request_types) == 0:
1046 outputRequest_types = False
1047
1048 code('''
1049// Auto generated C++ code started by $__file__:$__line__
1050// ${ident}: ${{self.short}}
1051
1052#include <sys/types.h>
1053#include <typeinfo>
1054#include <unistd.h>
1055
1056#include <cassert>
1057
1058#include "base/misc.hh"
1059#include "debug/RubySlicc.hh"
1060#include "mem/protocol/${ident}_Controller.hh"
1061#include "mem/protocol/${ident}_Event.hh"

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

1069#include "mem/protocol/Types.hh"
1070#include "mem/ruby/system/System.hh"
1071''')
1072
1073
1074 for include_path in includes:
1075 code('#include "${{include_path}}"')
1076
1077 port_to_buf_map, in_msg_bufs, msg_bufs = self.getBufferMaps(ident)
1078
1079 code('''
1080
1081using namespace std;
1082
1083void
1084${ident}_Controller::wakeup()
1085{
1086 int counter = 0;
1087 while (true) {
1088 unsigned char rejected[${{len(msg_bufs)}}];
1089 memset(rejected, 0, sizeof(unsigned char)*${{len(msg_bufs)}});
1090 // Some cases will put us into an infinite loop without this limit
1091 assert(counter <= m_transitions_per_cycle);
1092 if (counter == m_transitions_per_cycle) {
1093 // Count how often we are fully utilized
1094 m_fully_busy_cycles++;
1095
1096 // Wakeup in another cycle and try again
1097 scheduleEvent(Cycles(1));

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

1106 #
1107 for port in self.in_ports:
1108 code.indent()
1109 code('// ${ident}InPort $port')
1110 if port.pairs.has_key("rank"):
1111 code('m_cur_in_port = ${{port.pairs["rank"]}};')
1112 else:
1113 code('m_cur_in_port = 0;')
1114 if port in port_to_buf_map:
1115 code('try {')
1116 code.indent()
1117 code('${{port["c_code_in_port"]}}')
1088 code.dedent()
1118
1119 if port in port_to_buf_map:
1120 code.dedent()
1121 code('''
1122 } catch (const RejectException & e) {
1123 rejected[${{port_to_buf_map[port]}}]++;
1124 }
1125''')
1126 code.dedent()
1127 code('')
1128
1129 code.dedent()
1130 code.dedent()
1131 code('''
1095 break; // If we got this far, we have nothing left todo
1132 // If we got this far, we have nothing left todo or something went
1133 // wrong''')
1134 for buf_name, ports in in_msg_bufs.items():
1135 if len(ports) > 1:
1136 # only produce checks when a buffer is shared by multiple ports
1137 code('''
1138 if (${{buf_name}}->isReady() && rejected[${{port_to_buf_map[ports[0]]}}] == ${{len(ports)}})
1139 {
1140 // no port claimed the message on the top of this buffer
1141 panic("Runtime Error at Ruby Time: %d. "
1142 "All ports rejected a message. "
1143 "You are probably sending a message type to this controller "
1144 "over a virtual network that do not define an in_port for "
1145 "the incoming message type.\\n",
1146 Cycles(1));
1147 }
1148''')
1149 code('''
1150 break;
1151 }
1152}
1153''')
1154
1155 code.write(path, "%s_Wakeup.cc" % self.ident)
1156
1157 def printCSwitch(self, path):
1158 '''Output switch statement for transition table'''

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

1220 code('doTransitionWorker(event, state, next_state, m_tbe_ptr, m_cache_entry_ptr, addr);')
1221 elif self.TBEType != None:
1222 code('doTransitionWorker(event, state, next_state, m_tbe_ptr, addr);')
1223 elif self.EntryType != None:
1224 code('doTransitionWorker(event, state, next_state, m_cache_entry_ptr, addr);')
1225 else:
1226 code('doTransitionWorker(event, state, next_state, addr);')
1227
1228 port_to_buf_map, in_msg_bufs, msg_bufs = self.getBufferMaps(ident)
1229
1230 code('''
1231
1232if (result == TransitionResult_Valid) {
1233 DPRINTF(RubyGenerated, "next_state: %s\\n",
1234 ${ident}_State_to_string(next_state));
1235 countTransition(state, event);
1236
1237 DPRINTFR(ProtocolTrace, "%15d %3s %10s%20s %6s>%-6s %s %s\\n",

--- 344 unchanged lines hidden ---