StateMachine.py revision 6888
15331Sgblack@eecs.umich.edu# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 25331Sgblack@eecs.umich.edu# Copyright (c) 2009 The Hewlett-Packard Development Company 35331Sgblack@eecs.umich.edu# All rights reserved. 45331Sgblack@eecs.umich.edu# 55331Sgblack@eecs.umich.edu# Redistribution and use in source and binary forms, with or without 65331Sgblack@eecs.umich.edu# modification, are permitted provided that the following conditions are 75331Sgblack@eecs.umich.edu# met: redistributions of source code must retain the above copyright 85331Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer; 95331Sgblack@eecs.umich.edu# redistributions in binary form must reproduce the above copyright 105331Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the 115331Sgblack@eecs.umich.edu# documentation and/or other materials provided with the distribution; 125331Sgblack@eecs.umich.edu# neither the name of the copyright holders nor the names of its 135331Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from 145331Sgblack@eecs.umich.edu# this software without specific prior written permission. 155331Sgblack@eecs.umich.edu# 165331Sgblack@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175331Sgblack@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185331Sgblack@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195331Sgblack@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205331Sgblack@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215331Sgblack@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225331Sgblack@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235331Sgblack@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245331Sgblack@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255331Sgblack@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265331Sgblack@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275331Sgblack@eecs.umich.edu 285331Sgblack@eecs.umich.edufrom m5.util import code_formatter, orderdict 295331Sgblack@eecs.umich.edu 304276Sgblack@eecs.umich.edufrom slicc.symbols.Symbol import Symbol 314276Sgblack@eecs.umich.edufrom slicc.symbols.Var import Var 324276Sgblack@eecs.umich.eduimport slicc.generate.html as html 334276Sgblack@eecs.umich.edu 344276Sgblack@eecs.umich.edupython_class_map = {"int": "Int", 354276Sgblack@eecs.umich.edu "string": "String", 364276Sgblack@eecs.umich.edu "bool": "Bool", 374276Sgblack@eecs.umich.edu "CacheMemory": "RubyCache", 384276Sgblack@eecs.umich.edu "Sequencer": "RubySequencer", 394276Sgblack@eecs.umich.edu "DirectoryMemory": "RubyDirectoryMemory", 404276Sgblack@eecs.umich.edu "MemoryControl": "RubyMemoryControl", 414276Sgblack@eecs.umich.edu "DMASequencer": "DMASequencer" 424276Sgblack@eecs.umich.edu } 434276Sgblack@eecs.umich.edu 444276Sgblack@eecs.umich.educlass StateMachine(Symbol): 454276Sgblack@eecs.umich.edu def __init__(self, symtab, ident, location, pairs, config_parameters): 464276Sgblack@eecs.umich.edu super(StateMachine, self).__init__(symtab, ident, location, pairs) 474276Sgblack@eecs.umich.edu self.table = None 484276Sgblack@eecs.umich.edu self.config_parameters = config_parameters 494276Sgblack@eecs.umich.edu for param in config_parameters: 504276Sgblack@eecs.umich.edu if param.pointer: 514276Sgblack@eecs.umich.edu var = Var(symtab, param.name, location, param.type_ast.type, 524276Sgblack@eecs.umich.edu "(*m_%s_ptr)" % param.name, {}, self) 534276Sgblack@eecs.umich.edu else: 544276Sgblack@eecs.umich.edu var = Var(symtab, param.name, location, param.type_ast.type, 554276Sgblack@eecs.umich.edu "m_%s" % param.name, {}, self) 564276Sgblack@eecs.umich.edu self.symtab.registerSym(param.name, var) 574276Sgblack@eecs.umich.edu 584276Sgblack@eecs.umich.edu self.states = orderdict() 594276Sgblack@eecs.umich.edu self.events = orderdict() 604276Sgblack@eecs.umich.edu self.actions = orderdict() 614276Sgblack@eecs.umich.edu self.transitions = [] 624276Sgblack@eecs.umich.edu self.in_ports = [] 634276Sgblack@eecs.umich.edu self.functions = [] 644276Sgblack@eecs.umich.edu self.objects = [] 654276Sgblack@eecs.umich.edu 664276Sgblack@eecs.umich.edu self.message_buffer_names = [] 674276Sgblack@eecs.umich.edu 684276Sgblack@eecs.umich.edu def __repr__(self): 694276Sgblack@eecs.umich.edu return "[StateMachine: %s]" % self.ident 704276Sgblack@eecs.umich.edu 714276Sgblack@eecs.umich.edu def addState(self, state): 724276Sgblack@eecs.umich.edu assert self.table is None 734276Sgblack@eecs.umich.edu self.states[state.ident] = state 744276Sgblack@eecs.umich.edu 754276Sgblack@eecs.umich.edu def addEvent(self, event): 764276Sgblack@eecs.umich.edu assert self.table is None 774276Sgblack@eecs.umich.edu self.events[event.ident] = event 784276Sgblack@eecs.umich.edu 794276Sgblack@eecs.umich.edu def addAction(self, action): 804276Sgblack@eecs.umich.edu assert self.table is None 814276Sgblack@eecs.umich.edu 824276Sgblack@eecs.umich.edu # Check for duplicate action 834276Sgblack@eecs.umich.edu for other in self.actions.itervalues(): 844276Sgblack@eecs.umich.edu if action.ident == other.ident: 854276Sgblack@eecs.umich.edu action.warning("Duplicate action definition: %s" % action.ident) 864276Sgblack@eecs.umich.edu action.error("Duplicate action definition: %s" % action.ident) 874276Sgblack@eecs.umich.edu if action.short == other.short: 884276Sgblack@eecs.umich.edu other.warning("Duplicate action shorthand: %s" % other.ident) 894711Sgblack@eecs.umich.edu other.warning(" shorthand = %s" % other.short) 904276Sgblack@eecs.umich.edu action.warning("Duplicate action shorthand: %s" % action.ident) 914276Sgblack@eecs.umich.edu action.error(" shorthand = %s" % action.short) 925238Sgblack@eecs.umich.edu 935238Sgblack@eecs.umich.edu self.actions[action.ident] = action 945238Sgblack@eecs.umich.edu 955238Sgblack@eecs.umich.edu def addTransition(self, trans): 965238Sgblack@eecs.umich.edu assert self.table is None 975238Sgblack@eecs.umich.edu self.transitions.append(trans) 985238Sgblack@eecs.umich.edu 995238Sgblack@eecs.umich.edu def addInPort(self, var): 1005238Sgblack@eecs.umich.edu self.in_ports.append(var) 1015238Sgblack@eecs.umich.edu 1025238Sgblack@eecs.umich.edu def addFunc(self, func): 1035238Sgblack@eecs.umich.edu # register func in the symbol table 1045238Sgblack@eecs.umich.edu self.symtab.registerSym(str(func), func) 1055238Sgblack@eecs.umich.edu self.functions.append(func) 1065238Sgblack@eecs.umich.edu 1075238Sgblack@eecs.umich.edu def addObject(self, obj): 1085238Sgblack@eecs.umich.edu self.objects.append(obj) 1095238Sgblack@eecs.umich.edu 1105238Sgblack@eecs.umich.edu # Needs to be called before accessing the table 1115238Sgblack@eecs.umich.edu def buildTable(self): 1125238Sgblack@eecs.umich.edu assert self.table is None 1135238Sgblack@eecs.umich.edu 1145238Sgblack@eecs.umich.edu table = {} 1155238Sgblack@eecs.umich.edu 1165238Sgblack@eecs.umich.edu for trans in self.transitions: 1175238Sgblack@eecs.umich.edu # Track which actions we touch so we know if we use them 1185238Sgblack@eecs.umich.edu # all -- really this should be done for all symbols as 1195238Sgblack@eecs.umich.edu # part of the symbol table, then only trigger it for 1205238Sgblack@eecs.umich.edu # Actions, States, Events, etc. 1215238Sgblack@eecs.umich.edu 1225238Sgblack@eecs.umich.edu for action in trans.actions: 1235238Sgblack@eecs.umich.edu action.used = True 1245238Sgblack@eecs.umich.edu 1255238Sgblack@eecs.umich.edu index = (trans.state, trans.event) 1265238Sgblack@eecs.umich.edu if index in table: 1275238Sgblack@eecs.umich.edu table[index].warning("Duplicate transition: %s" % table[index]) 1285238Sgblack@eecs.umich.edu trans.error("Duplicate transition: %s" % trans) 1295238Sgblack@eecs.umich.edu table[index] = trans 1305238Sgblack@eecs.umich.edu 1315683Sgblack@eecs.umich.edu # Look at all actions to make sure we used them all 1325238Sgblack@eecs.umich.edu for action in self.actions.itervalues(): 1335238Sgblack@eecs.umich.edu if not action.used: 1345238Sgblack@eecs.umich.edu error_msg = "Unused action: %s" % action.ident 1355238Sgblack@eecs.umich.edu if "desc" in action: 1365238Sgblack@eecs.umich.edu error_msg += ", " + action.desc 1375238Sgblack@eecs.umich.edu action.warning(error_msg) 1385238Sgblack@eecs.umich.edu self.table = table 1395238Sgblack@eecs.umich.edu 1405291Sgblack@eecs.umich.edu def writeCodeFiles(self, path): 1415291Sgblack@eecs.umich.edu self.printControllerPython(path) 1425291Sgblack@eecs.umich.edu self.printControllerHH(path) 1435291Sgblack@eecs.umich.edu self.printControllerCC(path) 1445291Sgblack@eecs.umich.edu self.printCSwitch(path) 1455291Sgblack@eecs.umich.edu self.printCWakeup(path) 1465291Sgblack@eecs.umich.edu self.printProfilerCC(path) 1475291Sgblack@eecs.umich.edu self.printProfilerHH(path) 1485291Sgblack@eecs.umich.edu 1495292Sgblack@eecs.umich.edu for func in self.functions: 1505292Sgblack@eecs.umich.edu func.writeCodeFiles(path) 1515292Sgblack@eecs.umich.edu 1525292Sgblack@eecs.umich.edu def printControllerPython(self, path): 1535292Sgblack@eecs.umich.edu code = code_formatter() 1545292Sgblack@eecs.umich.edu ident = self.ident 1555292Sgblack@eecs.umich.edu py_ident = "%s_Controller" % ident 1565292Sgblack@eecs.umich.edu c_ident = "%s_Controller" % self.ident 1575292Sgblack@eecs.umich.edu code(''' 1585238Sgblack@eecs.umich.edufrom m5.params import * 1595238Sgblack@eecs.umich.edufrom m5.SimObject import SimObject 1605359Sgblack@eecs.umich.edufrom Controller import RubyController 1615238Sgblack@eecs.umich.edu 1625238Sgblack@eecs.umich.educlass $py_ident(RubyController): 1635238Sgblack@eecs.umich.edu type = '$py_ident' 1644276Sgblack@eecs.umich.edu''') 1654276Sgblack@eecs.umich.edu code.indent() 1665789Sgblack@eecs.umich.edu for param in self.config_parameters: 1675789Sgblack@eecs.umich.edu dflt_str = '' 1685789Sgblack@eecs.umich.edu if param.default is not None: 1695789Sgblack@eecs.umich.edu dflt_str = str(param.default) + ', ' 1705789Sgblack@eecs.umich.edu if python_class_map.has_key(param.type_ast.type.c_ident): 1715789Sgblack@eecs.umich.edu python_type = python_class_map[param.type_ast.type.c_ident] 1725789Sgblack@eecs.umich.edu code('${{param.name}} = Param.${{python_type}}(${dflt_str}"")') 1735789Sgblack@eecs.umich.edu else: 1745789Sgblack@eecs.umich.edu self.error("Unknown c++ to python class conversion for c++ " \ 1755789Sgblack@eecs.umich.edu "type: '%s'. Please update the python_class_map " \ 1765789Sgblack@eecs.umich.edu "in StateMachine.py", param.type_ast.type.c_ident) 1775789Sgblack@eecs.umich.edu code.dedent() 1785789Sgblack@eecs.umich.edu code.write(path, '%s.py' % py_ident) 1795789Sgblack@eecs.umich.edu 1805789Sgblack@eecs.umich.edu 1815789Sgblack@eecs.umich.edu def printControllerHH(self, path): 1825789Sgblack@eecs.umich.edu '''Output the method declarations for the class declaration''' 1835789Sgblack@eecs.umich.edu code = code_formatter() 1845789Sgblack@eecs.umich.edu ident = self.ident 1855789Sgblack@eecs.umich.edu c_ident = "%s_Controller" % self.ident 1865789Sgblack@eecs.umich.edu 1875789Sgblack@eecs.umich.edu self.message_buffer_names = [] 1885789Sgblack@eecs.umich.edu 1895789Sgblack@eecs.umich.edu code(''' 1905789Sgblack@eecs.umich.edu/** \\file $ident.hh 1915789Sgblack@eecs.umich.edu * 1925789Sgblack@eecs.umich.edu * Auto generated C++ code started by $__file__:$__line__ 1935789Sgblack@eecs.umich.edu * Created by slicc definition of Module "${{self.short}}" 1945789Sgblack@eecs.umich.edu */ 1955789Sgblack@eecs.umich.edu 1965789Sgblack@eecs.umich.edu#ifndef ${ident}_CONTROLLER_H 1975789Sgblack@eecs.umich.edu#define ${ident}_CONTROLLER_H 1985789Sgblack@eecs.umich.edu 1995789Sgblack@eecs.umich.edu#include "params/$c_ident.hh" 2005789Sgblack@eecs.umich.edu 2015789Sgblack@eecs.umich.edu#include "mem/ruby/common/Global.hh" 2025789Sgblack@eecs.umich.edu#include "mem/ruby/common/Consumer.hh" 2035789Sgblack@eecs.umich.edu#include "mem/ruby/slicc_interface/AbstractController.hh" 2045789Sgblack@eecs.umich.edu#include "mem/protocol/TransitionResult.hh" 2055789Sgblack@eecs.umich.edu#include "mem/protocol/Types.hh" 2065789Sgblack@eecs.umich.edu#include "mem/protocol/${ident}_Profiler.hh" 2075789Sgblack@eecs.umich.edu''') 2085789Sgblack@eecs.umich.edu 2095789Sgblack@eecs.umich.edu seen_types = set() 2105789Sgblack@eecs.umich.edu for var in self.objects: 2115789Sgblack@eecs.umich.edu if var.type.ident not in seen_types and not var.type.isPrimitive: 2125789Sgblack@eecs.umich.edu code('#include "mem/protocol/${{var.type.c_ident}}.hh"') 2135789Sgblack@eecs.umich.edu seen_types.add(var.type.ident) 2145789Sgblack@eecs.umich.edu 2155789Sgblack@eecs.umich.edu # for adding information to the protocol debug trace 2165789Sgblack@eecs.umich.edu code(''' 2175789Sgblack@eecs.umich.eduextern stringstream ${ident}_transitionComment; 2185789Sgblack@eecs.umich.edu 2195789Sgblack@eecs.umich.educlass $c_ident : public AbstractController { 2205789Sgblack@eecs.umich.edu#ifdef CHECK_COHERENCE 2215789Sgblack@eecs.umich.edu#endif /* CHECK_COHERENCE */ 2225789Sgblack@eecs.umich.edupublic: 2235789Sgblack@eecs.umich.edu typedef ${c_ident}Params Params; 2245789Sgblack@eecs.umich.edu $c_ident(const Params *p); 2255789Sgblack@eecs.umich.edu static int getNumControllers(); 2265789Sgblack@eecs.umich.edu void init(); 2275789Sgblack@eecs.umich.edu MessageBuffer* getMandatoryQueue() const; 2285789Sgblack@eecs.umich.edu const int & getVersion() const; 2295789Sgblack@eecs.umich.edu const string toString() const; 2305789Sgblack@eecs.umich.edu const string getName() const; 2315789Sgblack@eecs.umich.edu const MachineType getMachineType() const; 2325789Sgblack@eecs.umich.edu void initNetworkPtr(Network* net_ptr) { m_net_ptr = net_ptr; } 2335789Sgblack@eecs.umich.edu void print(ostream& out) const; 2345789Sgblack@eecs.umich.edu void printConfig(ostream& out) const; 2355789Sgblack@eecs.umich.edu void wakeup(); 2365789Sgblack@eecs.umich.edu void printStats(ostream& out) const { s_profiler.dumpStats(out); } 2375789Sgblack@eecs.umich.edu void clearStats() { s_profiler.clearStats(); } 2385789Sgblack@eecs.umich.edu void blockOnQueue(Address addr, MessageBuffer* port); 2395789Sgblack@eecs.umich.edu void unblock(Address addr); 2405789Sgblack@eecs.umich.eduprivate: 2415789Sgblack@eecs.umich.edu''') 2425789Sgblack@eecs.umich.edu 2435789Sgblack@eecs.umich.edu code.indent() 2445789Sgblack@eecs.umich.edu # added by SS 2455789Sgblack@eecs.umich.edu for param in self.config_parameters: 2465789Sgblack@eecs.umich.edu if param.pointer: 2475789Sgblack@eecs.umich.edu code('${{param.type_ast.type}}* m_${{param.ident}}_ptr;') 2485789Sgblack@eecs.umich.edu else: 2495789Sgblack@eecs.umich.edu code('${{param.type_ast.type}} m_${{param.ident}};') 2505789Sgblack@eecs.umich.edu 2515789Sgblack@eecs.umich.edu code(''' 2525789Sgblack@eecs.umich.eduint m_number_of_TBEs; 2535789Sgblack@eecs.umich.edu 2545789Sgblack@eecs.umich.eduTransitionResult doTransition(${ident}_Event event, ${ident}_State state, const Address& addr); // in ${ident}_Transitions.cc 2555789Sgblack@eecs.umich.eduTransitionResult doTransitionWorker(${ident}_Event event, ${ident}_State state, ${ident}_State& next_state, const Address& addr); // in ${ident}_Transitions.cc 2564712Sgblack@eecs.umich.edustring m_name; 2574711Sgblack@eecs.umich.eduint m_transitions_per_cycle; 2584712Sgblack@eecs.umich.eduint m_buffer_size; 2595659Sgblack@eecs.umich.eduint m_recycle_latency; 2604712Sgblack@eecs.umich.edumap< string, string > m_cfg; 2614276Sgblack@eecs.umich.eduNodeID m_version; 2624276Sgblack@eecs.umich.eduNetwork* m_net_ptr; 2634276Sgblack@eecs.umich.eduMachineID m_machineID; 2644276Sgblack@eecs.umich.edubool m_is_blocking; 2654276Sgblack@eecs.umich.edumap< Address, MessageBuffer* > m_block_map; 2664276Sgblack@eecs.umich.edu${ident}_Profiler s_profiler; 2674712Sgblack@eecs.umich.edustatic int m_num_controllers; 2684712Sgblack@eecs.umich.edu// Internal functions 2694730Sgblack@eecs.umich.edu''') 2704760Sgblack@eecs.umich.edu 2714730Sgblack@eecs.umich.edu for func in self.functions: 2725422Sgblack@eecs.umich.edu proto = func.prototype 2735422Sgblack@eecs.umich.edu if proto: 2745422Sgblack@eecs.umich.edu code('$proto') 2754276Sgblack@eecs.umich.edu 2764760Sgblack@eecs.umich.edu code(''' 2774760Sgblack@eecs.umich.edu 2784760Sgblack@eecs.umich.edu// Actions 2795020Sgblack@eecs.umich.edu''') 2805020Sgblack@eecs.umich.edu for action in self.actions.itervalues(): 2815020Sgblack@eecs.umich.edu code('/** \\brief ${{action.desc}} */') 2825020Sgblack@eecs.umich.edu code('void ${{action.ident}}(const Address& addr);') 2835020Sgblack@eecs.umich.edu 2845020Sgblack@eecs.umich.edu # the controller internal variables 2855020Sgblack@eecs.umich.edu code(''' 2865020Sgblack@eecs.umich.edu 2875020Sgblack@eecs.umich.edu// Object 2885020Sgblack@eecs.umich.edu''') 2895020Sgblack@eecs.umich.edu for var in self.objects: 2905020Sgblack@eecs.umich.edu th = var.get("template_hack", "") 2915020Sgblack@eecs.umich.edu code('${{var.type.c_ident}}$th* m_${{var.c_ident}}_ptr;') 2925020Sgblack@eecs.umich.edu 2934760Sgblack@eecs.umich.edu if var.type.ident == "MessageBuffer": 2944760Sgblack@eecs.umich.edu self.message_buffer_names.append("m_%s_ptr" % var.c_ident) 2954760Sgblack@eecs.umich.edu 2965020Sgblack@eecs.umich.edu code.dedent() 2975020Sgblack@eecs.umich.edu code('};') 2985020Sgblack@eecs.umich.edu code('#endif // ${ident}_CONTROLLER_H') 2995020Sgblack@eecs.umich.edu code.write(path, '%s.hh' % c_ident) 3005020Sgblack@eecs.umich.edu 3014760Sgblack@eecs.umich.edu def printControllerCC(self, path): 3024760Sgblack@eecs.umich.edu '''Output the actions for performing the actions''' 3034760Sgblack@eecs.umich.edu 3045020Sgblack@eecs.umich.edu code = code_formatter() 3055020Sgblack@eecs.umich.edu ident = self.ident 3065029Sgblack@eecs.umich.edu c_ident = "%s_Controller" % self.ident 3075029Sgblack@eecs.umich.edu 3085020Sgblack@eecs.umich.edu code(''' 3095020Sgblack@eecs.umich.edu/** \\file $ident.cc 3105020Sgblack@eecs.umich.edu * 3115020Sgblack@eecs.umich.edu * Auto generated C++ code started by $__file__:$__line__ 3124760Sgblack@eecs.umich.edu * Created by slicc definition of Module "${{self.short}}" 3134760Sgblack@eecs.umich.edu */ 3144760Sgblack@eecs.umich.edu 3155030Sgblack@eecs.umich.edu#include "mem/ruby/common/Global.hh" 3165030Sgblack@eecs.umich.edu#include "mem/ruby/slicc_interface/RubySlicc_includes.hh" 3175020Sgblack@eecs.umich.edu#include "mem/protocol/${ident}_Controller.hh" 3185020Sgblack@eecs.umich.edu#include "mem/protocol/${ident}_State.hh" 3194760Sgblack@eecs.umich.edu#include "mem/protocol/${ident}_Event.hh" 3204760Sgblack@eecs.umich.edu#include "mem/protocol/Types.hh" 3214276Sgblack@eecs.umich.edu#include "mem/ruby/system/System.hh" 3224276Sgblack@eecs.umich.edu''') 3235331Sgblack@eecs.umich.edu 3245331Sgblack@eecs.umich.edu # include object classes 3255331Sgblack@eecs.umich.edu seen_types = set() 3265331Sgblack@eecs.umich.edu for var in self.objects: 3275331Sgblack@eecs.umich.edu if var.type.ident not in seen_types and not var.type.isPrimitive: 3285331Sgblack@eecs.umich.edu code('#include "mem/protocol/${{var.type.c_ident}}.hh"') 3295331Sgblack@eecs.umich.edu seen_types.add(var.type.ident) 3305331Sgblack@eecs.umich.edu 3315331Sgblack@eecs.umich.edu code(''' 3325331Sgblack@eecs.umich.edu$c_ident * 3335331Sgblack@eecs.umich.edu${c_ident}Params::create() 3345331Sgblack@eecs.umich.edu{ 3355331Sgblack@eecs.umich.edu return new $c_ident(this); 3365331Sgblack@eecs.umich.edu} 3375331Sgblack@eecs.umich.edu 3384276Sgblack@eecs.umich.edu 3395020Sgblack@eecs.umich.eduint $c_ident::m_num_controllers = 0; 3405020Sgblack@eecs.umich.edu 3415020Sgblack@eecs.umich.edustringstream ${ident}_transitionComment; 3425296Sgblack@eecs.umich.edu#define APPEND_TRANSITION_COMMENT(str) (${ident}_transitionComment << str) 3435020Sgblack@eecs.umich.edu/** \\brief constructor */ 3445241Sgblack@eecs.umich.edu$c_ident::$c_ident(const Params *p) 3455020Sgblack@eecs.umich.edu : AbstractController(p) 3465020Sgblack@eecs.umich.edu{ 3475020Sgblack@eecs.umich.edu m_version = p->version; 3485020Sgblack@eecs.umich.edu m_transitions_per_cycle = p->transitions_per_cycle; 3495020Sgblack@eecs.umich.edu m_buffer_size = p->buffer_size; 3505020Sgblack@eecs.umich.edu m_recycle_latency = p->recycle_latency; 3515020Sgblack@eecs.umich.edu m_number_of_TBEs = p->number_of_TBEs; 3525020Sgblack@eecs.umich.edu''') 3535020Sgblack@eecs.umich.edu code.indent() 3545020Sgblack@eecs.umich.edu 3555020Sgblack@eecs.umich.edu # 3564276Sgblack@eecs.umich.edu # After initializing the universal machine parameters, initialize the 3575020Sgblack@eecs.umich.edu # this machines config parameters. Also detemine if these configuration 3585020Sgblack@eecs.umich.edu # params include a sequencer. This information will be used later for 3595020Sgblack@eecs.umich.edu # contecting the sequencer back to the L1 cache controller. 3605031Sgblack@eecs.umich.edu # 3615031Sgblack@eecs.umich.edu contains_sequencer = False 3625031Sgblack@eecs.umich.edu for param in self.config_parameters: 3635031Sgblack@eecs.umich.edu if param.name == "sequencer" or param.name == "dma_sequencer": 3645020Sgblack@eecs.umich.edu contains_sequencer = True 3655020Sgblack@eecs.umich.edu if param.pointer: 3665020Sgblack@eecs.umich.edu code('m_${{param.name}}_ptr = p->${{param.name}};') 3675020Sgblack@eecs.umich.edu else: 3685020Sgblack@eecs.umich.edu code('m_${{param.name}} = p->${{param.name}};') 3695020Sgblack@eecs.umich.edu 3705020Sgblack@eecs.umich.edu # 3715020Sgblack@eecs.umich.edu # For the l1 cache controller, add the special atomic support which 3725020Sgblack@eecs.umich.edu # includes passing the sequencer a pointer to the controller. 3735020Sgblack@eecs.umich.edu # 3745020Sgblack@eecs.umich.edu if self.ident == "L1Cache": 3755020Sgblack@eecs.umich.edu if not contains_sequencer: 3765020Sgblack@eecs.umich.edu self.error("The L1Cache controller must include the sequencer " \ 3775020Sgblack@eecs.umich.edu "configuration parameter") 3785020Sgblack@eecs.umich.edu 3795020Sgblack@eecs.umich.edu code(''' 3805020Sgblack@eecs.umich.edum_sequencer_ptr->setController(this); 3815020Sgblack@eecs.umich.edu''') 3825020Sgblack@eecs.umich.edu # 3835020Sgblack@eecs.umich.edu # For the DMA controller, pass the sequencer a pointer to the 3845020Sgblack@eecs.umich.edu # controller. 3855020Sgblack@eecs.umich.edu # 3865020Sgblack@eecs.umich.edu if self.ident == "DMA": 3875020Sgblack@eecs.umich.edu if not contains_sequencer: 3885020Sgblack@eecs.umich.edu self.error("The DMA controller must include the sequencer " \ 3895020Sgblack@eecs.umich.edu "configuration parameter") 3905020Sgblack@eecs.umich.edu 3915020Sgblack@eecs.umich.edu code(''' 3925058Sgblack@eecs.umich.edum_dma_sequencer_ptr->setController(this); 3935020Sgblack@eecs.umich.edu''') 3945020Sgblack@eecs.umich.edu 3955020Sgblack@eecs.umich.edu code('m_num_controllers++;') 3965020Sgblack@eecs.umich.edu for var in self.objects: 3975046Sgblack@eecs.umich.edu if var.ident.find("mandatoryQueue") >= 0: 3985046Sgblack@eecs.umich.edu code('m_${{var.c_ident}}_ptr = new ${{var.type.c_ident}}();') 3995046Sgblack@eecs.umich.edu 4005046Sgblack@eecs.umich.edu code.dedent() 4015020Sgblack@eecs.umich.edu code(''' 4025020Sgblack@eecs.umich.edu} 4035020Sgblack@eecs.umich.edu 4045020Sgblack@eecs.umich.eduvoid $c_ident::init() 4054276Sgblack@eecs.umich.edu{ 4064276Sgblack@eecs.umich.edu m_machineID.type = MachineType_${ident}; 4075149Sgblack@eecs.umich.edu m_machineID.num = m_version; 4085409Sgblack@eecs.umich.edu 4095149Sgblack@eecs.umich.edu // Objects 4104712Sgblack@eecs.umich.edu s_profiler.setVersion(m_version); 4114712Sgblack@eecs.umich.edu''') 4124712Sgblack@eecs.umich.edu 4134730Sgblack@eecs.umich.edu code.indent() 4144712Sgblack@eecs.umich.edu for var in self.objects: 4154276Sgblack@eecs.umich.edu vtype = var.type 4164276Sgblack@eecs.umich.edu vid = "m_%s_ptr" % var.c_ident 4174712Sgblack@eecs.umich.edu if "network" not in var: 4184712Sgblack@eecs.umich.edu # Not a network port object 4194712Sgblack@eecs.umich.edu if "primitive" in vtype: 4204712Sgblack@eecs.umich.edu code('$vid = new ${{vtype.c_ident}};') 4214712Sgblack@eecs.umich.edu if "default" in var: 4224712Sgblack@eecs.umich.edu code('(*$vid) = ${{var["default"]}};') 4234712Sgblack@eecs.umich.edu else: 4244712Sgblack@eecs.umich.edu # Normal Object 4254276Sgblack@eecs.umich.edu # added by SS 4264760Sgblack@eecs.umich.edu if "factory" in var: 4274760Sgblack@eecs.umich.edu code('$vid = ${{var["factory"]}};') 4284760Sgblack@eecs.umich.edu elif var.ident.find("mandatoryQueue") < 0: 4294760Sgblack@eecs.umich.edu th = var.get("template_hack", "") 4304760Sgblack@eecs.umich.edu expr = "%s = new %s%s" % (vid, vtype.c_ident, th) 4314760Sgblack@eecs.umich.edu 4324760Sgblack@eecs.umich.edu args = "" 4334760Sgblack@eecs.umich.edu if "non_obj" not in vtype and not vtype.isEnumeration: 4344760Sgblack@eecs.umich.edu if expr.find("TBETable") >= 0: 4354760Sgblack@eecs.umich.edu args = "m_number_of_TBEs" 4364760Sgblack@eecs.umich.edu else: 4374760Sgblack@eecs.umich.edu args = var.get("constructor_hack", "") 4384760Sgblack@eecs.umich.edu args = "(%s)" % args 4394760Sgblack@eecs.umich.edu 4404760Sgblack@eecs.umich.edu code('$expr$args;') 4414760Sgblack@eecs.umich.edu else: 4424760Sgblack@eecs.umich.edu code(';') 4434760Sgblack@eecs.umich.edu 4444760Sgblack@eecs.umich.edu code('assert($vid != NULL);') 4454760Sgblack@eecs.umich.edu 4464760Sgblack@eecs.umich.edu if "default" in var: 4474276Sgblack@eecs.umich.edu code('(*$vid) = ${{var["default"]}}; // Object default') 4485020Sgblack@eecs.umich.edu elif "default" in vtype: 4495020Sgblack@eecs.umich.edu code('(*$vid) = ${{vtype["default"]}}; // Type ${{vtype.ident}} default') 4505020Sgblack@eecs.umich.edu 4515020Sgblack@eecs.umich.edu # Set ordering 4525020Sgblack@eecs.umich.edu if "ordered" in var and "trigger_queue" not in var: 4535020Sgblack@eecs.umich.edu # A buffer 4545020Sgblack@eecs.umich.edu code('$vid->setOrdering(${{var["ordered"]}});') 4555020Sgblack@eecs.umich.edu 4565020Sgblack@eecs.umich.edu # Set randomization 4575020Sgblack@eecs.umich.edu if "random" in var: 4585020Sgblack@eecs.umich.edu # A buffer 4595020Sgblack@eecs.umich.edu code('$vid->setRandomization(${{var["random"]}});') 4605020Sgblack@eecs.umich.edu 4615020Sgblack@eecs.umich.edu # Set Priority 4625020Sgblack@eecs.umich.edu if vtype.isBuffer and \ 4635020Sgblack@eecs.umich.edu "rank" in var and "trigger_queue" not in var: 4645020Sgblack@eecs.umich.edu code('$vid->setPriority(${{var["rank"]}});') 4655020Sgblack@eecs.umich.edu else: 4665020Sgblack@eecs.umich.edu # Network port object 4675020Sgblack@eecs.umich.edu network = var["network"] 4685020Sgblack@eecs.umich.edu ordered = var["ordered"] 4695020Sgblack@eecs.umich.edu vnet = var["virtual_network"] 4705020Sgblack@eecs.umich.edu 4715020Sgblack@eecs.umich.edu assert var.machine is not None 4725020Sgblack@eecs.umich.edu code(''' 4735020Sgblack@eecs.umich.edu$vid = m_net_ptr->get${network}NetQueue(m_version+MachineType_base_number(string_to_MachineType("${{var.machine.ident}}")), $ordered, $vnet); 4745052Sgblack@eecs.umich.edu''') 4755052Sgblack@eecs.umich.edu 4765052Sgblack@eecs.umich.edu code('assert($vid != NULL);') 4775020Sgblack@eecs.umich.edu 4785020Sgblack@eecs.umich.edu # Set ordering 4795059Sgblack@eecs.umich.edu if "ordered" in var: 4805059Sgblack@eecs.umich.edu # A buffer 4815059Sgblack@eecs.umich.edu code('$vid->setOrdering(${{var["ordered"]}});') 4825059Sgblack@eecs.umich.edu 4835059Sgblack@eecs.umich.edu # Set randomization 4845059Sgblack@eecs.umich.edu if "random" in var: 4855059Sgblack@eecs.umich.edu # A buffer 4865020Sgblack@eecs.umich.edu code('$vid->setRandomization(${{var["random"]}})') 4874276Sgblack@eecs.umich.edu 4885020Sgblack@eecs.umich.edu # Set Priority 4895020Sgblack@eecs.umich.edu if "rank" in var: 4905020Sgblack@eecs.umich.edu code('$vid->setPriority(${{var["rank"]}})') 4915020Sgblack@eecs.umich.edu 4925020Sgblack@eecs.umich.edu # Set buffer size 4935020Sgblack@eecs.umich.edu if vtype.isBuffer: 4945020Sgblack@eecs.umich.edu code(''' 4955020Sgblack@eecs.umich.eduif (m_buffer_size > 0) { 4965020Sgblack@eecs.umich.edu $vid->setSize(m_buffer_size); 4975020Sgblack@eecs.umich.edu} 4985020Sgblack@eecs.umich.edu''') 4995020Sgblack@eecs.umich.edu 5005020Sgblack@eecs.umich.edu # set description (may be overriden later by port def) 5015020Sgblack@eecs.umich.edu code('$vid->setDescription("[Version " + int_to_string(m_version) + ", ${ident}, name=${{var.c_ident}}]");') 5025020Sgblack@eecs.umich.edu 5035020Sgblack@eecs.umich.edu # Set the queue consumers 5045020Sgblack@eecs.umich.edu code.insert_newline() 5055020Sgblack@eecs.umich.edu for port in self.in_ports: 5065020Sgblack@eecs.umich.edu code('${{port.code}}.setConsumer(this);') 5075020Sgblack@eecs.umich.edu 5085020Sgblack@eecs.umich.edu # Set the queue descriptions 5095020Sgblack@eecs.umich.edu code.insert_newline() 5105020Sgblack@eecs.umich.edu for port in self.in_ports: 5115020Sgblack@eecs.umich.edu code('${{port.code}}.setDescription("[Version " + int_to_string(m_version) + ", $ident, $port]");') 5125020Sgblack@eecs.umich.edu 5135020Sgblack@eecs.umich.edu # Initialize the transition profiling 5145020Sgblack@eecs.umich.edu code.insert_newline() 5155020Sgblack@eecs.umich.edu for trans in self.transitions: 5165020Sgblack@eecs.umich.edu # Figure out if we stall 5175020Sgblack@eecs.umich.edu stall = False 5185020Sgblack@eecs.umich.edu for action in trans.actions: 5195020Sgblack@eecs.umich.edu if action.ident == "z_stall": 5205020Sgblack@eecs.umich.edu stall = True 5215020Sgblack@eecs.umich.edu 5225020Sgblack@eecs.umich.edu # Only possible if it is not a 'z' case 5235020Sgblack@eecs.umich.edu if not stall: 5245047Sgblack@eecs.umich.edu state = "%s_State_%s" % (self.ident, trans.state.ident) 5255047Sgblack@eecs.umich.edu event = "%s_Event_%s" % (self.ident, trans.event.ident) 5265020Sgblack@eecs.umich.edu code('s_profiler.possibleTransition($state, $event);') 5275047Sgblack@eecs.umich.edu 5285020Sgblack@eecs.umich.edu # added by SS to initialize recycle_latency of message buffers 5295047Sgblack@eecs.umich.edu for buf in self.message_buffer_names: 5305020Sgblack@eecs.umich.edu code("$buf->setRecycleLatency(m_recycle_latency);") 5315020Sgblack@eecs.umich.edu 5325020Sgblack@eecs.umich.edu code.dedent() 5335020Sgblack@eecs.umich.edu code('}') 5344276Sgblack@eecs.umich.edu 5355020Sgblack@eecs.umich.edu has_mandatory_q = False 5365020Sgblack@eecs.umich.edu for port in self.in_ports: 5375020Sgblack@eecs.umich.edu if port.code.find("mandatoryQueue_ptr") >= 0: 5385020Sgblack@eecs.umich.edu has_mandatory_q = True 5395020Sgblack@eecs.umich.edu 5405020Sgblack@eecs.umich.edu if has_mandatory_q: 5415020Sgblack@eecs.umich.edu mq_ident = "m_%s_mandatoryQueue_ptr" % self.ident 5425020Sgblack@eecs.umich.edu else: 5435020Sgblack@eecs.umich.edu mq_ident = "NULL" 5445020Sgblack@eecs.umich.edu 5455020Sgblack@eecs.umich.edu code(''' 5465020Sgblack@eecs.umich.eduint $c_ident::getNumControllers() { 5475020Sgblack@eecs.umich.edu return m_num_controllers; 5485020Sgblack@eecs.umich.edu} 5495020Sgblack@eecs.umich.edu 5505020Sgblack@eecs.umich.eduMessageBuffer* $c_ident::getMandatoryQueue() const { 5515020Sgblack@eecs.umich.edu return $mq_ident; 5525020Sgblack@eecs.umich.edu} 5535020Sgblack@eecs.umich.edu 5545020Sgblack@eecs.umich.educonst int & $c_ident::getVersion() const{ 5555020Sgblack@eecs.umich.edu return m_version; 5565020Sgblack@eecs.umich.edu} 5575020Sgblack@eecs.umich.edu 5585020Sgblack@eecs.umich.educonst string $c_ident::toString() const{ 5594276Sgblack@eecs.umich.edu return "$c_ident"; 5605020Sgblack@eecs.umich.edu} 5615020Sgblack@eecs.umich.edu 5625020Sgblack@eecs.umich.educonst string $c_ident::getName() const{ 5635020Sgblack@eecs.umich.edu return m_name; 5645020Sgblack@eecs.umich.edu} 5655020Sgblack@eecs.umich.educonst MachineType $c_ident::getMachineType() const{ 5665020Sgblack@eecs.umich.edu return MachineType_${ident}; 5675020Sgblack@eecs.umich.edu} 5685020Sgblack@eecs.umich.edu 5695020Sgblack@eecs.umich.eduvoid $c_ident::blockOnQueue(Address addr, MessageBuffer* port) { 5705020Sgblack@eecs.umich.edu m_is_blocking = true; 5715020Sgblack@eecs.umich.edu m_block_map[addr] = port; 5725020Sgblack@eecs.umich.edu} 5735020Sgblack@eecs.umich.eduvoid $c_ident::unblock(Address addr) { 5745020Sgblack@eecs.umich.edu m_block_map.erase(addr); 5755020Sgblack@eecs.umich.edu if (m_block_map.size() == 0) { 5765020Sgblack@eecs.umich.edu m_is_blocking = false; 5775020Sgblack@eecs.umich.edu } 5785020Sgblack@eecs.umich.edu} 5795020Sgblack@eecs.umich.edu 5805020Sgblack@eecs.umich.eduvoid $c_ident::print(ostream& out) const { out << "[$c_ident " << m_version << "]"; } 5815020Sgblack@eecs.umich.edu 5825020Sgblack@eecs.umich.eduvoid $c_ident::printConfig(ostream& out) const { 5835020Sgblack@eecs.umich.edu out << "$c_ident config: " << m_name << endl; 5845020Sgblack@eecs.umich.edu out << " version: " << m_version << endl; 5855020Sgblack@eecs.umich.edu for (map<string, string>::const_iterator it = m_cfg.begin(); it != m_cfg.end(); it++) { 5865020Sgblack@eecs.umich.edu out << " " << (*it).first << ": " << (*it).second << endl; 5875020Sgblack@eecs.umich.edu } 5884276Sgblack@eecs.umich.edu} 5895020Sgblack@eecs.umich.edu 5905020Sgblack@eecs.umich.edu// Actions 5915020Sgblack@eecs.umich.edu''') 5925020Sgblack@eecs.umich.edu 5935238Sgblack@eecs.umich.edu for action in self.actions.itervalues(): 5945238Sgblack@eecs.umich.edu if "c_code" not in action: 5955238Sgblack@eecs.umich.edu continue 5965238Sgblack@eecs.umich.edu 5975238Sgblack@eecs.umich.edu code(''' 5985238Sgblack@eecs.umich.edu/** \\brief ${{action.desc}} */ 5995238Sgblack@eecs.umich.eduvoid $c_ident::${{action.ident}}(const Address& addr) 6005238Sgblack@eecs.umich.edu{ 6015238Sgblack@eecs.umich.edu DEBUG_MSG(GENERATED_COMP, HighPrio, "executing"); 6025238Sgblack@eecs.umich.edu ${{action["c_code"]}} 6035238Sgblack@eecs.umich.edu} 6045238Sgblack@eecs.umich.edu 6055238Sgblack@eecs.umich.edu''') 6065238Sgblack@eecs.umich.edu code.write(path, "%s.cc" % c_ident) 6075238Sgblack@eecs.umich.edu 6085238Sgblack@eecs.umich.edu def printCWakeup(self, path): 6095238Sgblack@eecs.umich.edu '''Output the wakeup loop for the events''' 6105238Sgblack@eecs.umich.edu 6115238Sgblack@eecs.umich.edu code = code_formatter() 6125238Sgblack@eecs.umich.edu ident = self.ident 6135238Sgblack@eecs.umich.edu 6145238Sgblack@eecs.umich.edu code(''' 6155238Sgblack@eecs.umich.edu// Auto generated C++ code started by $__file__:$__line__ 6165238Sgblack@eecs.umich.edu// ${ident}: ${{self.short}} 6175238Sgblack@eecs.umich.edu 6185238Sgblack@eecs.umich.edu#include "mem/ruby/common/Global.hh" 6195238Sgblack@eecs.umich.edu#include "mem/ruby/slicc_interface/RubySlicc_includes.hh" 6205238Sgblack@eecs.umich.edu#include "mem/protocol/${ident}_Controller.hh" 6215238Sgblack@eecs.umich.edu#include "mem/protocol/${ident}_State.hh" 6225238Sgblack@eecs.umich.edu#include "mem/protocol/${ident}_Event.hh" 6235238Sgblack@eecs.umich.edu#include "mem/protocol/Types.hh" 6245238Sgblack@eecs.umich.edu#include "mem/ruby/system/System.hh" 6255238Sgblack@eecs.umich.edu 6265238Sgblack@eecs.umich.eduvoid ${ident}_Controller::wakeup() 6275238Sgblack@eecs.umich.edu{ 6285238Sgblack@eecs.umich.edu 6295238Sgblack@eecs.umich.edu int counter = 0; 6305238Sgblack@eecs.umich.edu while (true) { 6315238Sgblack@eecs.umich.edu // Some cases will put us into an infinite loop without this limit 6325238Sgblack@eecs.umich.edu assert(counter <= m_transitions_per_cycle); 6335238Sgblack@eecs.umich.edu if (counter == m_transitions_per_cycle) { 6345238Sgblack@eecs.umich.edu g_system_ptr->getProfiler()->controllerBusy(m_machineID); // Count how often we\'re fully utilized 6355238Sgblack@eecs.umich.edu g_eventQueue_ptr->scheduleEvent(this, 1); // Wakeup in another cycle and try again 6365238Sgblack@eecs.umich.edu break; 6375238Sgblack@eecs.umich.edu } 6385238Sgblack@eecs.umich.edu''') 6395238Sgblack@eecs.umich.edu 6405238Sgblack@eecs.umich.edu code.indent() 6415238Sgblack@eecs.umich.edu code.indent() 6425238Sgblack@eecs.umich.edu 6435238Sgblack@eecs.umich.edu # InPorts 6445238Sgblack@eecs.umich.edu # 6455020Sgblack@eecs.umich.edu for port in self.in_ports: 6465020Sgblack@eecs.umich.edu code.indent() 6475020Sgblack@eecs.umich.edu code('// ${ident}InPort $port') 6485020Sgblack@eecs.umich.edu code('${{port["c_code_in_port"]}}') 6495020Sgblack@eecs.umich.edu code.dedent() 6505020Sgblack@eecs.umich.edu 6515020Sgblack@eecs.umich.edu code('') 6525020Sgblack@eecs.umich.edu 6535020Sgblack@eecs.umich.edu code.dedent() 6545020Sgblack@eecs.umich.edu code.dedent() 6555020Sgblack@eecs.umich.edu code(''' 6565020Sgblack@eecs.umich.edu break; // If we got this far, we have nothing left todo 6575020Sgblack@eecs.umich.edu } 6585238Sgblack@eecs.umich.edu} 6595238Sgblack@eecs.umich.edu''') 6605238Sgblack@eecs.umich.edu 6615238Sgblack@eecs.umich.edu code.write(path, "%s_Wakeup.cc" % self.ident) 6625238Sgblack@eecs.umich.edu 6635238Sgblack@eecs.umich.edu def printCSwitch(self, path): 6645238Sgblack@eecs.umich.edu '''Output switch statement for transition table''' 6655238Sgblack@eecs.umich.edu 6665238Sgblack@eecs.umich.edu code = code_formatter() 6675238Sgblack@eecs.umich.edu ident = self.ident 6685238Sgblack@eecs.umich.edu 6695238Sgblack@eecs.umich.edu code(''' 6705238Sgblack@eecs.umich.edu// Auto generated C++ code started by $__file__:$__line__ 6715238Sgblack@eecs.umich.edu// ${ident}: ${{self.short}} 6725238Sgblack@eecs.umich.edu 6735238Sgblack@eecs.umich.edu#include "mem/ruby/common/Global.hh" 6745238Sgblack@eecs.umich.edu#include "mem/protocol/${ident}_Controller.hh" 6755238Sgblack@eecs.umich.edu#include "mem/protocol/${ident}_State.hh" 6765238Sgblack@eecs.umich.edu#include "mem/protocol/${ident}_Event.hh" 6775238Sgblack@eecs.umich.edu#include "mem/protocol/Types.hh" 6785238Sgblack@eecs.umich.edu#include "mem/ruby/system/System.hh" 6795238Sgblack@eecs.umich.edu 6805238Sgblack@eecs.umich.edu#define HASH_FUN(state, event) ((int(state)*${ident}_Event_NUM)+int(event)) 6815238Sgblack@eecs.umich.edu 6825238Sgblack@eecs.umich.edu#define GET_TRANSITION_COMMENT() (${ident}_transitionComment.str()) 6835238Sgblack@eecs.umich.edu#define CLEAR_TRANSITION_COMMENT() (${ident}_transitionComment.str("")) 6845238Sgblack@eecs.umich.edu 6855238Sgblack@eecs.umich.eduTransitionResult ${ident}_Controller::doTransition(${ident}_Event event, ${ident}_State state, const Address& addr 6865238Sgblack@eecs.umich.edu) 6875238Sgblack@eecs.umich.edu{ 6885238Sgblack@eecs.umich.edu ${ident}_State next_state = state; 6895238Sgblack@eecs.umich.edu 6905238Sgblack@eecs.umich.edu DEBUG_NEWLINE(GENERATED_COMP, MedPrio); 6915238Sgblack@eecs.umich.edu DEBUG_MSG(GENERATED_COMP, MedPrio, *this); 6925238Sgblack@eecs.umich.edu DEBUG_EXPR(GENERATED_COMP, MedPrio, g_eventQueue_ptr->getTime()); 6935238Sgblack@eecs.umich.edu DEBUG_EXPR(GENERATED_COMP, MedPrio,state); 6945238Sgblack@eecs.umich.edu DEBUG_EXPR(GENERATED_COMP, MedPrio,event); 6955238Sgblack@eecs.umich.edu DEBUG_EXPR(GENERATED_COMP, MedPrio,addr); 6965238Sgblack@eecs.umich.edu 6975238Sgblack@eecs.umich.edu TransitionResult result = doTransitionWorker(event, state, next_state, addr); 6985238Sgblack@eecs.umich.edu 6995238Sgblack@eecs.umich.edu if (result == TransitionResult_Valid) { 7005238Sgblack@eecs.umich.edu DEBUG_EXPR(GENERATED_COMP, MedPrio, next_state); 7015238Sgblack@eecs.umich.edu DEBUG_NEWLINE(GENERATED_COMP, MedPrio); 7025238Sgblack@eecs.umich.edu s_profiler.countTransition(state, event); 7035238Sgblack@eecs.umich.edu if (Debug::getProtocolTrace()) { 7045238Sgblack@eecs.umich.edu g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr, 7055238Sgblack@eecs.umich.edu ${ident}_State_to_string(state), 7065238Sgblack@eecs.umich.edu ${ident}_Event_to_string(event), 7075238Sgblack@eecs.umich.edu ${ident}_State_to_string(next_state), GET_TRANSITION_COMMENT()); 7085238Sgblack@eecs.umich.edu } 7095238Sgblack@eecs.umich.edu CLEAR_TRANSITION_COMMENT(); 7105020Sgblack@eecs.umich.edu ${ident}_setState(addr, next_state); 7115020Sgblack@eecs.umich.edu 7125020Sgblack@eecs.umich.edu } else if (result == TransitionResult_ResourceStall) { 7135020Sgblack@eecs.umich.edu if (Debug::getProtocolTrace()) { 7145020Sgblack@eecs.umich.edu g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr, 7155020Sgblack@eecs.umich.edu ${ident}_State_to_string(state), 7165020Sgblack@eecs.umich.edu ${ident}_Event_to_string(event), 7175020Sgblack@eecs.umich.edu ${ident}_State_to_string(next_state), 7185020Sgblack@eecs.umich.edu "Resource Stall"); 7195020Sgblack@eecs.umich.edu } 7205020Sgblack@eecs.umich.edu } else if (result == TransitionResult_ProtocolStall) { 7214276Sgblack@eecs.umich.edu DEBUG_MSG(GENERATED_COMP, HighPrio, "stalling"); 7225020Sgblack@eecs.umich.edu DEBUG_NEWLINE(GENERATED_COMP, MedPrio); 7235020Sgblack@eecs.umich.edu if (Debug::getProtocolTrace()) { 7245020Sgblack@eecs.umich.edu g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr, 7255020Sgblack@eecs.umich.edu ${ident}_State_to_string(state), 7265020Sgblack@eecs.umich.edu ${ident}_Event_to_string(event), 7275020Sgblack@eecs.umich.edu ${ident}_State_to_string(next_state), 7285020Sgblack@eecs.umich.edu "Protocol Stall"); 7295020Sgblack@eecs.umich.edu } 7305020Sgblack@eecs.umich.edu } 7315020Sgblack@eecs.umich.edu 7325020Sgblack@eecs.umich.edu return result; 7335020Sgblack@eecs.umich.edu} 7345020Sgblack@eecs.umich.edu 7355020Sgblack@eecs.umich.eduTransitionResult ${ident}_Controller::doTransitionWorker(${ident}_Event event, ${ident}_State state, ${ident}_State& next_state, const Address& addr 7365020Sgblack@eecs.umich.edu) 7375020Sgblack@eecs.umich.edu{ 7385020Sgblack@eecs.umich.edu switch(HASH_FUN(state, event)) { 7395020Sgblack@eecs.umich.edu''') 7405020Sgblack@eecs.umich.edu 7415020Sgblack@eecs.umich.edu # This map will allow suppress generating duplicate code 7425020Sgblack@eecs.umich.edu cases = orderdict() 7435020Sgblack@eecs.umich.edu 7445020Sgblack@eecs.umich.edu for trans in self.transitions: 7455020Sgblack@eecs.umich.edu case_string = "%s_State_%s, %s_Event_%s" % \ 7465020Sgblack@eecs.umich.edu (self.ident, trans.state.ident, self.ident, trans.event.ident) 7475020Sgblack@eecs.umich.edu 7485020Sgblack@eecs.umich.edu case = code_formatter() 7495020Sgblack@eecs.umich.edu # Only set next_state if it changes 7505020Sgblack@eecs.umich.edu if trans.state != trans.nextState: 7515020Sgblack@eecs.umich.edu ns_ident = trans.nextState.ident 7524276Sgblack@eecs.umich.edu case('next_state = ${ident}_State_${ns_ident};') 7534727Sgblack@eecs.umich.edu 7544727Sgblack@eecs.umich.edu actions = trans.actions 7554727Sgblack@eecs.umich.edu 7564727Sgblack@eecs.umich.edu # Check for resources 7574727Sgblack@eecs.umich.edu case_sorter = [] 7584727Sgblack@eecs.umich.edu res = trans.resources 7594727Sgblack@eecs.umich.edu for key,val in res.iteritems(): 7604727Sgblack@eecs.umich.edu if key.type.ident != "DNUCAStopTable": 7614727Sgblack@eecs.umich.edu val = ''' 7624727Sgblack@eecs.umich.eduif (!%s.areNSlotsAvailable(%s)) { 7634727Sgblack@eecs.umich.edu return TransitionResult_ResourceStall; 7644727Sgblack@eecs.umich.edu} 7654727Sgblack@eecs.umich.edu''' % (key.code, val) 7664727Sgblack@eecs.umich.edu case_sorter.append(val) 7674727Sgblack@eecs.umich.edu 7684727Sgblack@eecs.umich.edu 7694727Sgblack@eecs.umich.edu # Emit the code sequences in a sorted order. This makes the 7704727Sgblack@eecs.umich.edu # output deterministic (without this the output order can vary 7714727Sgblack@eecs.umich.edu # since Map's keys() on a vector of pointers is not deterministic 7724727Sgblack@eecs.umich.edu for c in sorted(case_sorter): 7734727Sgblack@eecs.umich.edu case("$c") 7744760Sgblack@eecs.umich.edu 7754760Sgblack@eecs.umich.edu # Figure out if we stall 7764760Sgblack@eecs.umich.edu stall = False 7774760Sgblack@eecs.umich.edu for action in actions: 7784760Sgblack@eecs.umich.edu if action.ident == "z_stall": 7794760Sgblack@eecs.umich.edu stall = True 7804760Sgblack@eecs.umich.edu break 7814760Sgblack@eecs.umich.edu 7824760Sgblack@eecs.umich.edu if stall: 7834760Sgblack@eecs.umich.edu case('return TransitionResult_ProtocolStall;') 7844760Sgblack@eecs.umich.edu else: 7854760Sgblack@eecs.umich.edu for action in actions: 7864760Sgblack@eecs.umich.edu case('${{action.ident}}(addr);') 7874760Sgblack@eecs.umich.edu case('return TransitionResult_Valid;') 7884760Sgblack@eecs.umich.edu 7894760Sgblack@eecs.umich.edu case = str(case) 7904760Sgblack@eecs.umich.edu 7914760Sgblack@eecs.umich.edu # Look to see if this transition code is unique. 7924760Sgblack@eecs.umich.edu if case not in cases: 7934760Sgblack@eecs.umich.edu cases[case] = [] 7944276Sgblack@eecs.umich.edu 7954276Sgblack@eecs.umich.edu cases[case].append(case_string) 7964712Sgblack@eecs.umich.edu 7974712Sgblack@eecs.umich.edu # Walk through all of the unique code blocks and spit out the 7985659Sgblack@eecs.umich.edu # corresponding case statement elements 7995659Sgblack@eecs.umich.edu for case,transitions in cases.iteritems(): 8005659Sgblack@eecs.umich.edu # Iterative over all the multiple transitions that share 8015659Sgblack@eecs.umich.edu # the same code 8025659Sgblack@eecs.umich.edu for trans in transitions: 8035659Sgblack@eecs.umich.edu code(' case HASH_FUN($trans):') 8045659Sgblack@eecs.umich.edu code(' {') 8055659Sgblack@eecs.umich.edu code(' $case') 8065240Sgblack@eecs.umich.edu code(' }') 8074712Sgblack@eecs.umich.edu 8084712Sgblack@eecs.umich.edu code(''' 8094712Sgblack@eecs.umich.edu default: 8104712Sgblack@eecs.umich.edu WARN_EXPR(m_version); 8114276Sgblack@eecs.umich.edu WARN_EXPR(g_eventQueue_ptr->getTime()); 8124276Sgblack@eecs.umich.edu WARN_EXPR(addr); 8134712Sgblack@eecs.umich.edu WARN_EXPR(event); 8144712Sgblack@eecs.umich.edu WARN_EXPR(state); 8154712Sgblack@eecs.umich.edu ERROR_MSG(\"Invalid transition\"); 8165240Sgblack@eecs.umich.edu } 8174712Sgblack@eecs.umich.edu return TransitionResult_Valid; 8184712Sgblack@eecs.umich.edu} 8195238Sgblack@eecs.umich.edu''') 8205238Sgblack@eecs.umich.edu code.write(path, "%s_Transitions.cc" % self.ident) 8215238Sgblack@eecs.umich.edu 8225238Sgblack@eecs.umich.edu def printProfilerHH(self, path): 8235238Sgblack@eecs.umich.edu code = code_formatter() 8245238Sgblack@eecs.umich.edu ident = self.ident 8255238Sgblack@eecs.umich.edu 8265238Sgblack@eecs.umich.edu code(''' 8275238Sgblack@eecs.umich.edu// Auto generated C++ code started by $__file__:$__line__ 8285238Sgblack@eecs.umich.edu// ${ident}: ${{self.short}} 8295238Sgblack@eecs.umich.edu 8305238Sgblack@eecs.umich.edu#ifndef ${ident}_PROFILER_H 8315238Sgblack@eecs.umich.edu#define ${ident}_PROFILER_H 8325238Sgblack@eecs.umich.edu 8335238Sgblack@eecs.umich.edu#include "mem/ruby/common/Global.hh" 8344724Sgblack@eecs.umich.edu#include "mem/protocol/${ident}_State.hh" 8354276Sgblack@eecs.umich.edu#include "mem/protocol/${ident}_Event.hh" 8364276Sgblack@eecs.umich.edu 8374864Sgblack@eecs.umich.educlass ${ident}_Profiler { 8384864Sgblack@eecs.umich.edu public: 8394712Sgblack@eecs.umich.edu ${ident}_Profiler(); 8405240Sgblack@eecs.umich.edu void setVersion(int version); 8414712Sgblack@eecs.umich.edu void countTransition(${ident}_State state, ${ident}_Event event); 8424712Sgblack@eecs.umich.edu void possibleTransition(${ident}_State state, ${ident}_Event event); 8434746Sgblack@eecs.umich.edu void dumpStats(ostream& out) const; 8444746Sgblack@eecs.umich.edu void clearStats(); 8454746Sgblack@eecs.umich.edu 8464746Sgblack@eecs.umich.edu private: 8474746Sgblack@eecs.umich.edu int m_counters[${ident}_State_NUM][${ident}_Event_NUM]; 8484276Sgblack@eecs.umich.edu int m_event_counters[${ident}_Event_NUM]; 8494276Sgblack@eecs.umich.edu bool m_possible[${ident}_State_NUM][${ident}_Event_NUM]; 8504712Sgblack@eecs.umich.edu int m_version; 8515240Sgblack@eecs.umich.edu}; 8525240Sgblack@eecs.umich.edu 8535240Sgblack@eecs.umich.edu#endif // ${ident}_PROFILER_H 8545240Sgblack@eecs.umich.edu''') 8555240Sgblack@eecs.umich.edu code.write(path, "%s_Profiler.hh" % self.ident) 8565240Sgblack@eecs.umich.edu 8575240Sgblack@eecs.umich.edu def printProfilerCC(self, path): 8585240Sgblack@eecs.umich.edu code = code_formatter() 8595240Sgblack@eecs.umich.edu ident = self.ident 8605240Sgblack@eecs.umich.edu 8615240Sgblack@eecs.umich.edu code(''' 8625240Sgblack@eecs.umich.edu// Auto generated C++ code started by $__file__:$__line__ 8635238Sgblack@eecs.umich.edu// ${ident}: ${{self.short}} 8645332Sgblack@eecs.umich.edu 8655332Sgblack@eecs.umich.edu#include "mem/protocol/${ident}_Profiler.hh" 8664746Sgblack@eecs.umich.edu 8674746Sgblack@eecs.umich.edu${ident}_Profiler::${ident}_Profiler() 8684746Sgblack@eecs.umich.edu{ 8694746Sgblack@eecs.umich.edu for (int state = 0; state < ${ident}_State_NUM; state++) { 8704746Sgblack@eecs.umich.edu for (int event = 0; event < ${ident}_Event_NUM; event++) { 8714276Sgblack@eecs.umich.edu m_possible[state][event] = false; 8724276Sgblack@eecs.umich.edu m_counters[state][event] = 0; 8735815Sgblack@eecs.umich.edu } 8745815Sgblack@eecs.umich.edu } 8755238Sgblack@eecs.umich.edu for (int event = 0; event < ${ident}_Event_NUM; event++) { 8765238Sgblack@eecs.umich.edu m_event_counters[event] = 0; 8775238Sgblack@eecs.umich.edu } 8785238Sgblack@eecs.umich.edu} 8795238Sgblack@eecs.umich.eduvoid ${ident}_Profiler::setVersion(int version) 8805238Sgblack@eecs.umich.edu{ 8815238Sgblack@eecs.umich.edu m_version = version; 8825238Sgblack@eecs.umich.edu} 8835238Sgblack@eecs.umich.eduvoid ${ident}_Profiler::clearStats() 8845238Sgblack@eecs.umich.edu{ 8855238Sgblack@eecs.umich.edu for (int state = 0; state < ${ident}_State_NUM; state++) { 8865238Sgblack@eecs.umich.edu for (int event = 0; event < ${ident}_Event_NUM; event++) { 8875238Sgblack@eecs.umich.edu m_counters[state][event] = 0; 8885020Sgblack@eecs.umich.edu } 8895020Sgblack@eecs.umich.edu } 8905020Sgblack@eecs.umich.edu 8915020Sgblack@eecs.umich.edu for (int event = 0; event < ${ident}_Event_NUM; event++) { 8925020Sgblack@eecs.umich.edu m_event_counters[event] = 0; 8935020Sgblack@eecs.umich.edu } 8945020Sgblack@eecs.umich.edu} 8955020Sgblack@eecs.umich.eduvoid ${ident}_Profiler::countTransition(${ident}_State state, ${ident}_Event event) 8965020Sgblack@eecs.umich.edu{ 8975020Sgblack@eecs.umich.edu assert(m_possible[state][event]); 8985020Sgblack@eecs.umich.edu m_counters[state][event]++; 8995020Sgblack@eecs.umich.edu m_event_counters[event]++; 9005020Sgblack@eecs.umich.edu} 9015020Sgblack@eecs.umich.eduvoid ${ident}_Profiler::possibleTransition(${ident}_State state, ${ident}_Event event) 9025020Sgblack@eecs.umich.edu{ 9035020Sgblack@eecs.umich.edu m_possible[state][event] = true; 9045020Sgblack@eecs.umich.edu} 9055020Sgblack@eecs.umich.eduvoid ${ident}_Profiler::dumpStats(ostream& out) const 9065020Sgblack@eecs.umich.edu{ 9075020Sgblack@eecs.umich.edu out << " --- ${ident} " << m_version << " ---" << endl; 9085020Sgblack@eecs.umich.edu out << " - Event Counts -" << endl; 9095020Sgblack@eecs.umich.edu for (int event = 0; event < ${ident}_Event_NUM; event++) { 9105020Sgblack@eecs.umich.edu int count = m_event_counters[event]; 9115020Sgblack@eecs.umich.edu out << (${ident}_Event) event << " " << count << endl; 9125020Sgblack@eecs.umich.edu } 9135020Sgblack@eecs.umich.edu out << endl; 9145020Sgblack@eecs.umich.edu out << " - Transitions -" << endl; 9155020Sgblack@eecs.umich.edu for (int state = 0; state < ${ident}_State_NUM; state++) { 9165020Sgblack@eecs.umich.edu for (int event = 0; event < ${ident}_Event_NUM; event++) { 9174276Sgblack@eecs.umich.edu if (m_possible[state][event]) { 9185814Sgblack@eecs.umich.edu int count = m_counters[state][event]; 9195814Sgblack@eecs.umich.edu out << (${ident}_State) state << " " << (${ident}_Event) event << " " << count; 9205814Sgblack@eecs.umich.edu if (count == 0) { 9215814Sgblack@eecs.umich.edu out << " <-- "; 9225814Sgblack@eecs.umich.edu } 9235020Sgblack@eecs.umich.edu out << endl; 9245020Sgblack@eecs.umich.edu } 9255020Sgblack@eecs.umich.edu } 9265020Sgblack@eecs.umich.edu out << endl; 9275020Sgblack@eecs.umich.edu } 9285020Sgblack@eecs.umich.edu} 9295020Sgblack@eecs.umich.edu''') 9305020Sgblack@eecs.umich.edu code.write(path, "%s_Profiler.cc" % self.ident) 9315020Sgblack@eecs.umich.edu 9325020Sgblack@eecs.umich.edu # ************************** 9335020Sgblack@eecs.umich.edu # ******* HTML Files ******* 9345020Sgblack@eecs.umich.edu # ************************** 9355020Sgblack@eecs.umich.edu def frameRef(self, click_href, click_target, over_href, over_target_num, 9365020Sgblack@eecs.umich.edu text): 9375020Sgblack@eecs.umich.edu code = code_formatter(fix_newlines=False) 9385020Sgblack@eecs.umich.edu code("""<A href=\"$click_href\" target=\"$click_target\" onMouseOver=\"if (parent.frames[$over_target_num].location != parent.location + '$over_href') { parent.frames[$over_target_num].location='$over_href' }\" >${{html.formatShorthand(text)}}</A>""") 9395020Sgblack@eecs.umich.edu return str(code) 9405020Sgblack@eecs.umich.edu 9415020Sgblack@eecs.umich.edu def writeHTMLFiles(self, path): 9425020Sgblack@eecs.umich.edu # Create table with no row hilighted 9435020Sgblack@eecs.umich.edu self.printHTMLTransitions(path, None) 9445020Sgblack@eecs.umich.edu 9455020Sgblack@eecs.umich.edu # Generate transition tables 9465020Sgblack@eecs.umich.edu for state in self.states.itervalues(): 9475020Sgblack@eecs.umich.edu self.printHTMLTransitions(path, state) 9485020Sgblack@eecs.umich.edu 9495020Sgblack@eecs.umich.edu # Generate action descriptions 9505020Sgblack@eecs.umich.edu for action in self.actions.itervalues(): 9515020Sgblack@eecs.umich.edu name = "%s_action_%s.html" % (self.ident, action.ident) 9525020Sgblack@eecs.umich.edu code = html.createSymbol(action, "Action") 9535020Sgblack@eecs.umich.edu code.write(path, name) 9545020Sgblack@eecs.umich.edu 9555020Sgblack@eecs.umich.edu # Generate state descriptions 9565020Sgblack@eecs.umich.edu for state in self.states.itervalues(): 9575020Sgblack@eecs.umich.edu name = "%s_State_%s.html" % (self.ident, state.ident) 9585020Sgblack@eecs.umich.edu code = html.createSymbol(state, "State") 9595020Sgblack@eecs.umich.edu code.write(path, name) 9604276Sgblack@eecs.umich.edu 9615020Sgblack@eecs.umich.edu # Generate event descriptions 9625020Sgblack@eecs.umich.edu for event in self.events.itervalues(): 9635020Sgblack@eecs.umich.edu name = "%s_Event_%s.html" % (self.ident, event.ident) 9645020Sgblack@eecs.umich.edu code = html.createSymbol(event, "Event") 9655020Sgblack@eecs.umich.edu code.write(path, name) 9665020Sgblack@eecs.umich.edu 9675020Sgblack@eecs.umich.edu def printHTMLTransitions(self, path, active_state): 9685020Sgblack@eecs.umich.edu code = code_formatter() 9695020Sgblack@eecs.umich.edu 9705020Sgblack@eecs.umich.edu code(''' 9715020Sgblack@eecs.umich.edu<HTML><BODY link="blue" vlink="blue"> 9725020Sgblack@eecs.umich.edu 9735020Sgblack@eecs.umich.edu<H1 align="center">${{html.formatShorthand(self.short)}}: 9745020Sgblack@eecs.umich.edu''') 9755020Sgblack@eecs.umich.edu code.indent() 9765020Sgblack@eecs.umich.edu for i,machine in enumerate(self.symtab.getAllType(StateMachine)): 9775020Sgblack@eecs.umich.edu mid = machine.ident 9785020Sgblack@eecs.umich.edu if i != 0: 9795020Sgblack@eecs.umich.edu extra = " - " 9805020Sgblack@eecs.umich.edu else: 9815020Sgblack@eecs.umich.edu extra = "" 9825020Sgblack@eecs.umich.edu if machine == self: 9835020Sgblack@eecs.umich.edu code('$extra$mid') 9845020Sgblack@eecs.umich.edu else: 9854276Sgblack@eecs.umich.edu code('$extra<A target="Table" href="${mid}_table.html">$mid</A>') 9865022Sgblack@eecs.umich.edu code.dedent() 9875022Sgblack@eecs.umich.edu 9885022Sgblack@eecs.umich.edu code(""" 9895022Sgblack@eecs.umich.edu</H1> 9905022Sgblack@eecs.umich.edu 9915022Sgblack@eecs.umich.edu<TABLE border=1> 9925022Sgblack@eecs.umich.edu<TR> 9935022Sgblack@eecs.umich.edu <TH> </TH> 9945022Sgblack@eecs.umich.edu""") 9955022Sgblack@eecs.umich.edu 9965022Sgblack@eecs.umich.edu for event in self.events.itervalues(): 9975022Sgblack@eecs.umich.edu href = "%s_Event_%s.html" % (self.ident, event.ident) 9985022Sgblack@eecs.umich.edu ref = self.frameRef(href, "Status", href, "1", event.short) 9995022Sgblack@eecs.umich.edu code('<TH bgcolor=white>$ref</TH>') 10005022Sgblack@eecs.umich.edu 10015022Sgblack@eecs.umich.edu code('</TR>') 10025022Sgblack@eecs.umich.edu # -- Body of table 10035022Sgblack@eecs.umich.edu for state in self.states.itervalues(): 10045022Sgblack@eecs.umich.edu # -- Each row 10055022Sgblack@eecs.umich.edu if state == active_state: 10065022Sgblack@eecs.umich.edu color = "yellow" 10075022Sgblack@eecs.umich.edu else: 10085022Sgblack@eecs.umich.edu color = "white" 10095022Sgblack@eecs.umich.edu 10105022Sgblack@eecs.umich.edu click = "%s_table_%s.html" % (self.ident, state.ident) 10115022Sgblack@eecs.umich.edu over = "%s_State_%s.html" % (self.ident, state.ident) 10125022Sgblack@eecs.umich.edu text = html.formatShorthand(state.short) 10135022Sgblack@eecs.umich.edu ref = self.frameRef(click, "Table", over, "1", state.short) 10145022Sgblack@eecs.umich.edu code(''' 10155022Sgblack@eecs.umich.edu<TR> 10165022Sgblack@eecs.umich.edu <TH bgcolor=$color>$ref</TH> 10175022Sgblack@eecs.umich.edu''') 10185022Sgblack@eecs.umich.edu 10195022Sgblack@eecs.umich.edu # -- One column for each event 10204276Sgblack@eecs.umich.edu for event in self.events.itervalues(): 10215020Sgblack@eecs.umich.edu trans = self.table.get((state,event), None) 10225020Sgblack@eecs.umich.edu if trans is None: 10235020Sgblack@eecs.umich.edu # This is the no transition case 10245020Sgblack@eecs.umich.edu if state == active_state: 10255020Sgblack@eecs.umich.edu color = "#C0C000" 10265020Sgblack@eecs.umich.edu else: 10275020Sgblack@eecs.umich.edu color = "lightgrey" 10285020Sgblack@eecs.umich.edu 10295020Sgblack@eecs.umich.edu code('<TD bgcolor=$color> </TD>') 10305020Sgblack@eecs.umich.edu continue 10315020Sgblack@eecs.umich.edu 10325020Sgblack@eecs.umich.edu next = trans.nextState 10335020Sgblack@eecs.umich.edu stall_action = False 10345020Sgblack@eecs.umich.edu 10355020Sgblack@eecs.umich.edu # -- Get the actions 10365020Sgblack@eecs.umich.edu for action in trans.actions: 10375020Sgblack@eecs.umich.edu if action.ident == "z_stall" or \ 10385020Sgblack@eecs.umich.edu action.ident == "zz_recycleMandatoryQueue": 10395020Sgblack@eecs.umich.edu stall_action = True 10405020Sgblack@eecs.umich.edu 10415020Sgblack@eecs.umich.edu # -- Print out "actions/next-state" 10425020Sgblack@eecs.umich.edu if stall_action: 10435020Sgblack@eecs.umich.edu if state == active_state: 10445020Sgblack@eecs.umich.edu color = "#C0C000" 10454276Sgblack@eecs.umich.edu else: 10464276Sgblack@eecs.umich.edu color = "lightgrey" 10475022Sgblack@eecs.umich.edu 10485022Sgblack@eecs.umich.edu elif active_state and next.ident == active_state.ident: 10495022Sgblack@eecs.umich.edu color = "aqua" 10505022Sgblack@eecs.umich.edu elif state == active_state: 10515022Sgblack@eecs.umich.edu color = "yellow" 10525022Sgblack@eecs.umich.edu else: 10535022Sgblack@eecs.umich.edu color = "white" 10545022Sgblack@eecs.umich.edu 10555022Sgblack@eecs.umich.edu fix = code.nofix() 10565022Sgblack@eecs.umich.edu code('<TD bgcolor=$color>') 10575022Sgblack@eecs.umich.edu for action in trans.actions: 10585022Sgblack@eecs.umich.edu href = "%s_action_%s.html" % (self.ident, action.ident) 10595022Sgblack@eecs.umich.edu ref = self.frameRef(href, "Status", href, "1", 10605022Sgblack@eecs.umich.edu action.short) 10615022Sgblack@eecs.umich.edu code(' $ref\n') 10625022Sgblack@eecs.umich.edu if next != state: 10635022Sgblack@eecs.umich.edu if trans.actions: 10645022Sgblack@eecs.umich.edu code('/') 10655022Sgblack@eecs.umich.edu click = "%s_table_%s.html" % (self.ident, next.ident) 10665022Sgblack@eecs.umich.edu over = "%s_State_%s.html" % (self.ident, next.ident) 10675022Sgblack@eecs.umich.edu ref = self.frameRef(click, "Table", over, "1", next.short) 10685022Sgblack@eecs.umich.edu code("$ref") 10695022Sgblack@eecs.umich.edu code("</TD>\n") 10705022Sgblack@eecs.umich.edu code.fix(fix) 10715022Sgblack@eecs.umich.edu 10725022Sgblack@eecs.umich.edu # -- Each row 10735022Sgblack@eecs.umich.edu if state == active_state: 10745022Sgblack@eecs.umich.edu color = "yellow" 10754276Sgblack@eecs.umich.edu else: 10765020Sgblack@eecs.umich.edu color = "white" 10775020Sgblack@eecs.umich.edu 10785020Sgblack@eecs.umich.edu click = "%s_table_%s.html" % (self.ident, state.ident) 10795020Sgblack@eecs.umich.edu over = "%s_State_%s.html" % (self.ident, state.ident) 10805020Sgblack@eecs.umich.edu ref = self.frameRef(click, "Table", over, "1", state.short) 10815020Sgblack@eecs.umich.edu code(''' 10825020Sgblack@eecs.umich.edu <TH bgcolor=$color>$ref</TH> 10835020Sgblack@eecs.umich.edu</TR> 10845020Sgblack@eecs.umich.edu''') 10855020Sgblack@eecs.umich.edu code(''' 10865020Sgblack@eecs.umich.edu<TR> 10875020Sgblack@eecs.umich.edu <TH> </TH> 10885020Sgblack@eecs.umich.edu''') 10895020Sgblack@eecs.umich.edu 10905020Sgblack@eecs.umich.edu for event in self.events.itervalues(): 10915020Sgblack@eecs.umich.edu href = "%s_Event_%s.html" % (self.ident, event.ident) 10925020Sgblack@eecs.umich.edu ref = self.frameRef(href, "Status", href, "1", event.short) 10935020Sgblack@eecs.umich.edu code('<TH bgcolor=white>$ref</TH>') 10945020Sgblack@eecs.umich.edu code(''' 10955020Sgblack@eecs.umich.edu</TR> 10965020Sgblack@eecs.umich.edu</TABLE> 10975020Sgblack@eecs.umich.edu</BODY></HTML> 10985020Sgblack@eecs.umich.edu''') 10995020Sgblack@eecs.umich.edu 11004276Sgblack@eecs.umich.edu 11014276Sgblack@eecs.umich.edu if active_state: 11024276Sgblack@eecs.umich.edu name = "%s_table_%s.html" % (self.ident, active_state.ident) 11034276Sgblack@eecs.umich.edu else: 11044276Sgblack@eecs.umich.edu name = "%s_table.html" % self.ident 11054276Sgblack@eecs.umich.edu code.write(path, name) 11064276Sgblack@eecs.umich.edu 1107__all__ = [ "StateMachine" ] 1108