StateMachine.py revision 6881
12292SN/A# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 27597Sminkyu.jeong@arm.com# Copyright (c) 2009 The Hewlett-Packard Development Company 37597Sminkyu.jeong@arm.com# All rights reserved. 47597Sminkyu.jeong@arm.com# 57597Sminkyu.jeong@arm.com# Redistribution and use in source and binary forms, with or without 67597Sminkyu.jeong@arm.com# modification, are permitted provided that the following conditions are 77597Sminkyu.jeong@arm.com# met: redistributions of source code must retain the above copyright 87597Sminkyu.jeong@arm.com# notice, this list of conditions and the following disclaimer; 97597Sminkyu.jeong@arm.com# redistributions in binary form must reproduce the above copyright 107597Sminkyu.jeong@arm.com# notice, this list of conditions and the following disclaimer in the 117597Sminkyu.jeong@arm.com# documentation and/or other materials provided with the distribution; 127597Sminkyu.jeong@arm.com# neither the name of the copyright holders nor the names of its 137597Sminkyu.jeong@arm.com# contributors may be used to endorse or promote products derived from 142292SN/A# this software without specific prior written permission. 152292SN/A# 162292SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172292SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182292SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192292SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202292SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212292SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222292SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232292SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242292SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252292SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262292SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272292SN/A 282292SN/Afrom m5.util import code_formatter, orderdict 292292SN/A 302292SN/Afrom slicc.symbols.Symbol import Symbol 312292SN/Afrom slicc.symbols.Var import Var 322292SN/Aimport slicc.generate.html as html 332292SN/A 342292SN/Aclass StateMachine(Symbol): 352292SN/A def __init__(self, symtab, ident, location, pairs, config_parameters): 362292SN/A super(StateMachine, self).__init__(symtab, ident, location, pairs) 372292SN/A self.table = None 382292SN/A self.config_parameters = config_parameters 392689Sktlim@umich.edu for param in config_parameters: 402689Sktlim@umich.edu var = Var(symtab, param.name, location, param.type_ast.type, 412689Sktlim@umich.edu "m_%s" % param.name, {}, self) 422292SN/A self.symtab.registerSym(param.name, var) 432292SN/A 443326Sktlim@umich.edu self.states = orderdict() 458229Snate@binkert.org self.events = orderdict() 466658Snate@binkert.org self.actions = orderdict() 472733Sktlim@umich.edu self.transitions = [] 482907Sktlim@umich.edu self.in_ports = [] 492292SN/A self.functions = [] 508232Snate@binkert.org self.objects = [] 518232Snate@binkert.org 528232Snate@binkert.org self.message_buffer_names = [] 532722Sktlim@umich.edu 542669Sktlim@umich.edu def __repr__(self): 552292SN/A return "[StateMachine: %s]" % self.ident 562790Sktlim@umich.edu 572790Sktlim@umich.edu def addState(self, state): 582790Sktlim@umich.edu assert self.table is None 592790Sktlim@umich.edu self.states[state.ident] = state 602669Sktlim@umich.edu 612678Sktlim@umich.edu def addEvent(self, event): 622678Sktlim@umich.edu assert self.table is None 638581Ssteve.reinhardt@amd.com self.events[event.ident] = event 648581Ssteve.reinhardt@amd.com 652292SN/A def addAction(self, action): 662292SN/A assert self.table is None 672292SN/A 682669Sktlim@umich.edu # Check for duplicate action 692292SN/A for other in self.actions.itervalues(): 702678Sktlim@umich.edu if action.ident == other.ident: 712292SN/A action.warning("Duplicate action definition: %s" % action.ident) 722678Sktlim@umich.edu action.error("Duplicate action definition: %s" % action.ident) 732678Sktlim@umich.edu if action.short == other.short: 742678Sktlim@umich.edu other.warning("Duplicate action shorthand: %s" % other.ident) 754319Sktlim@umich.edu other.warning(" shorthand = %s" % other.short) 764319Sktlim@umich.edu action.warning("Duplicate action shorthand: %s" % action.ident) 774319Sktlim@umich.edu action.error(" shorthand = %s" % action.short) 784319Sktlim@umich.edu 794319Sktlim@umich.edu self.actions[action.ident] = action 802678Sktlim@umich.edu 812678Sktlim@umich.edu def addTransition(self, trans): 822292SN/A assert self.table is None 832678Sktlim@umich.edu self.transitions.append(trans) 842678Sktlim@umich.edu 855336Shines@cs.fsu.edu def addInPort(self, var): 862678Sktlim@umich.edu self.in_ports.append(var) 874873Sstever@eecs.umich.edu 882678Sktlim@umich.edu def addFunc(self, func): 892292SN/A # register func in the symbol table 902678Sktlim@umich.edu self.symtab.registerSym(str(func), func) 912678Sktlim@umich.edu self.functions.append(func) 922678Sktlim@umich.edu 932678Sktlim@umich.edu def addObject(self, obj): 942678Sktlim@umich.edu self.objects.append(obj) 952678Sktlim@umich.edu 967852SMatt.Horsnell@arm.com # Needs to be called before accessing the table 977852SMatt.Horsnell@arm.com def buildTable(self): 982344SN/A assert self.table is None 992678Sktlim@umich.edu 1002678Sktlim@umich.edu table = {} 1014986Ssaidi@eecs.umich.edu 1024986Ssaidi@eecs.umich.edu for trans in self.transitions: 1036974Stjones1@inf.ed.ac.uk # Track which actions we touch so we know if we use them 1046974Stjones1@inf.ed.ac.uk # all -- really this should be done for all symbols as 1056974Stjones1@inf.ed.ac.uk # part of the symbol table, then only trigger it for 1066974Stjones1@inf.ed.ac.uk # Actions, States, Events, etc. 1076974Stjones1@inf.ed.ac.uk 1086974Stjones1@inf.ed.ac.uk for action in trans.actions: 1096974Stjones1@inf.ed.ac.uk action.used = True 1102678Sktlim@umich.edu 1112820Sktlim@umich.edu index = (trans.state, trans.event) 1122678Sktlim@umich.edu if index in table: 1132678Sktlim@umich.edu table[index].warning("Duplicate transition: %s" % table[index]) 1146974Stjones1@inf.ed.ac.uk trans.error("Duplicate transition: %s" % trans) 1156974Stjones1@inf.ed.ac.uk table[index] = trans 1166974Stjones1@inf.ed.ac.uk 1176974Stjones1@inf.ed.ac.uk # Look at all actions to make sure we used them all 1186974Stjones1@inf.ed.ac.uk for action in self.actions.itervalues(): 1196974Stjones1@inf.ed.ac.uk if not action.used: 1202678Sktlim@umich.edu error_msg = "Unused action: %s" % action.ident 1212678Sktlim@umich.edu if "desc" in action: 1222678Sktlim@umich.edu error_msg += ", " + action.desc 1232678Sktlim@umich.edu action.warning(error_msg) 1242678Sktlim@umich.edu self.table = table 1252344SN/A 1262307SN/A def writeCodeFiles(self, path): 1276974Stjones1@inf.ed.ac.uk self.printControllerPython(path) 1286974Stjones1@inf.ed.ac.uk self.printControllerHH(path) 1296974Stjones1@inf.ed.ac.uk self.printControllerCC(path) 1306974Stjones1@inf.ed.ac.uk self.printCSwitch(path) 1312678Sktlim@umich.edu self.printCWakeup(path) 1324032Sktlim@umich.edu self.printProfilerCC(path) 1332678Sktlim@umich.edu self.printProfilerHH(path) 1342292SN/A 1352292SN/A for func in self.functions: 1362292SN/A func.writeCodeFiles(path) 1372292SN/A 1388545Ssaidi@eecs.umich.edu def printControllerPython(self, path): 1392678Sktlim@umich.edu code = code_formatter() 1406974Stjones1@inf.ed.ac.uk ident = self.ident 1412292SN/A py_ident = "%s_Controller" % ident 1422292SN/A c_ident = "%s_Controller" % self.ident 1432292SN/A code(''' 1442292SN/Afrom m5.params import * 1452292SN/Afrom m5.SimObject import SimObject 1465529Snate@binkert.orgfrom Controller import RubyController 1475529Snate@binkert.org 1485529Snate@binkert.orgclass $py_ident(RubyController): 1492292SN/A type = '$py_ident' 1504329Sktlim@umich.edu''') 1514329Sktlim@umich.edu code.indent() 1524329Sktlim@umich.edu for param in self.config_parameters: 1534329Sktlim@umich.edu dflt_str = '' 1542292SN/A if param.default is not None: 1552307SN/A dflt_str = str(param.default) + ', ' 1562307SN/A code('${{param.name}} = Param.Int(${dflt_str}"")') 1578545Ssaidi@eecs.umich.edu code.dedent() 1588545Ssaidi@eecs.umich.edu code.write(path, '%s.py' % py_ident) 1592907Sktlim@umich.edu 1602907Sktlim@umich.edu 1612292SN/A def printControllerHH(self, path): 1622292SN/A '''Output the method declarations for the class declaration''' 1632329SN/A code = code_formatter() 1642329SN/A ident = self.ident 1652329SN/A c_ident = "%s_Controller" % self.ident 1662292SN/A 1672292SN/A self.message_buffer_names = [] 1682292SN/A 1692292SN/A code(''' 1708199SAli.Saidi@ARM.com/** \\file $ident.hh 1718199SAli.Saidi@ARM.com * 1728199SAli.Saidi@ARM.com * Auto generated C++ code started by $__file__:$__line__ 1732292SN/A * Created by slicc definition of Module "${{self.short}}" 1742292SN/A */ 1752292SN/A 1762292SN/A#ifndef ${ident}_CONTROLLER_H 1772292SN/A#define ${ident}_CONTROLLER_H 1782292SN/A 1792292SN/A#include "params/$c_ident.hh" 1803492Sktlim@umich.edu 1812329SN/A#include "mem/ruby/common/Global.hh" 1822292SN/A#include "mem/ruby/common/Consumer.hh" 1832292SN/A#include "mem/ruby/slicc_interface/AbstractController.hh" 1842292SN/A#include "mem/protocol/TransitionResult.hh" 1852292SN/A#include "mem/protocol/Types.hh" 1862292SN/A#include "mem/protocol/${ident}_Profiler.hh" 1872292SN/A''') 1882292SN/A 1892292SN/A seen_types = set() 1902292SN/A for var in self.objects: 1912292SN/A if var.type.ident not in seen_types and not var.type.isPrimitive: 1922292SN/A code('#include "mem/protocol/${{var.type.c_ident}}.hh"') 1938247Snate@binkert.org seen_types.add(var.type.ident) 1942292SN/A 1952292SN/A # for adding information to the protocol debug trace 1962292SN/A code(''' 1972292SN/Aextern stringstream ${ident}_transitionComment; 1982292SN/A 1992727Sktlim@umich.educlass $c_ident : public AbstractController { 2002727Sktlim@umich.edu#ifdef CHECK_COHERENCE 2012727Sktlim@umich.edu#endif /* CHECK_COHERENCE */ 2022727Sktlim@umich.edupublic: 2032727Sktlim@umich.edu typedef ${c_ident}Params Params; 2042727Sktlim@umich.edu $c_ident(const Params *p); 2052727Sktlim@umich.edu static int getNumControllers(); 2062727Sktlim@umich.edu void init(); 2072727Sktlim@umich.edu MessageBuffer* getMandatoryQueue() const; 2082727Sktlim@umich.edu const int & getVersion() const; 2092727Sktlim@umich.edu const string toString() const; 2102727Sktlim@umich.edu const string getName() const; 2112727Sktlim@umich.edu const MachineType getMachineType() const; 2122727Sktlim@umich.edu void initNetworkPtr(Network* net_ptr) { m_net_ptr = net_ptr; } 2132727Sktlim@umich.edu void print(ostream& out) const; 2142727Sktlim@umich.edu void printConfig(ostream& out) const; 2152727Sktlim@umich.edu void wakeup(); 2162727Sktlim@umich.edu void printStats(ostream& out) const { s_profiler.dumpStats(out); } 2172361SN/A void clearStats() { s_profiler.clearStats(); } 2182361SN/A void blockOnQueue(Address addr, MessageBuffer* port); 2192361SN/A void unblock(Address addr); 2202361SN/Aprivate: 2212727Sktlim@umich.edu''') 2222727Sktlim@umich.edu 2232727Sktlim@umich.edu code.indent() 2242727Sktlim@umich.edu # added by SS 2252727Sktlim@umich.edu for param in self.config_parameters: 2262727Sktlim@umich.edu code('int m_${{param.ident}};') 2272727Sktlim@umich.edu 2282727Sktlim@umich.edu code(''' 2292727Sktlim@umich.eduint m_number_of_TBEs; 2302727Sktlim@umich.edu 2312727Sktlim@umich.eduTransitionResult doTransition(${ident}_Event event, ${ident}_State state, const Address& addr); // in ${ident}_Transitions.cc 2322727Sktlim@umich.eduTransitionResult doTransitionWorker(${ident}_Event event, ${ident}_State state, ${ident}_State& next_state, const Address& addr); // in ${ident}_Transitions.cc 2332727Sktlim@umich.edustring m_name; 2342727Sktlim@umich.eduint m_transitions_per_cycle; 2352727Sktlim@umich.eduint m_buffer_size; 2362727Sktlim@umich.eduint m_recycle_latency; 2372727Sktlim@umich.edumap< string, string > m_cfg; 2382727Sktlim@umich.eduNodeID m_version; 2392727Sktlim@umich.eduNetwork* m_net_ptr; 2402727Sktlim@umich.eduMachineID m_machineID; 2412727Sktlim@umich.edubool m_is_blocking; 2422727Sktlim@umich.edumap< Address, MessageBuffer* > m_block_map; 2432727Sktlim@umich.edu${ident}_Profiler s_profiler; 2444329Sktlim@umich.edustatic int m_num_controllers; 2454329Sktlim@umich.edu// Internal functions 2464329Sktlim@umich.edu''') 2474329Sktlim@umich.edu 2484329Sktlim@umich.edu for func in self.functions: 2494329Sktlim@umich.edu proto = func.prototype 2504329Sktlim@umich.edu if proto: 2514329Sktlim@umich.edu code('$proto') 2524329Sktlim@umich.edu 2534329Sktlim@umich.edu code(''' 2544329Sktlim@umich.edu 2554329Sktlim@umich.edu// Actions 2564329Sktlim@umich.edu''') 2572292SN/A for action in self.actions.itervalues(): 2582292SN/A code('/** \\brief ${{action.desc}} */') 2592292SN/A code('void ${{action.ident}}(const Address& addr);') 2602292SN/A 2612292SN/A # the controller internal variables 2622292SN/A code(''' 2632292SN/A 2642292SN/A// Object 2652292SN/A''') 2662292SN/A for var in self.objects: 2672292SN/A th = var.get("template_hack", "") 2682292SN/A code('${{var.type.c_ident}}$th* m_${{var.c_ident}}_ptr;') 2692292SN/A 2702292SN/A if var.type.ident == "MessageBuffer": 2712307SN/A self.message_buffer_names.append("m_%s_ptr" % var.c_ident) 2722307SN/A 2732307SN/A code.dedent() 2742367SN/A code('};') 2752367SN/A code('#endif // ${ident}_CONTROLLER_H') 2762307SN/A code.write(path, '%s.hh' % c_ident) 2772367SN/A 2782307SN/A def printControllerCC(self, path): 2792329SN/A '''Output the actions for performing the actions''' 2802307SN/A 2812307SN/A code = code_formatter() 2822307SN/A ident = self.ident 2832307SN/A c_ident = "%s_Controller" % self.ident 2842307SN/A 2852307SN/A code(''' 2862307SN/A/** \\file $ident.cc 2872307SN/A * 2882307SN/A * Auto generated C++ code started by $__file__:$__line__ 2892307SN/A * Created by slicc definition of Module "${{self.short}}" 2902307SN/A */ 2912307SN/A 2922307SN/A#include "mem/ruby/common/Global.hh" 2932307SN/A#include "mem/ruby/slicc_interface/RubySlicc_includes.hh" 2942307SN/A#include "mem/protocol/${ident}_Controller.hh" 2952329SN/A#include "mem/protocol/${ident}_State.hh" 2962307SN/A#include "mem/protocol/${ident}_Event.hh" 2972307SN/A#include "mem/protocol/Types.hh" 2982307SN/A#include "mem/ruby/system/System.hh" 2992307SN/A''') 3002307SN/A 3012307SN/A # include object classes 3028545Ssaidi@eecs.umich.edu seen_types = set() 3038545Ssaidi@eecs.umich.edu for var in self.objects: 3048545Ssaidi@eecs.umich.edu if var.type.ident not in seen_types and not var.type.isPrimitive: 3052307SN/A code('#include "mem/protocol/${{var.type.c_ident}}.hh"') 3062307SN/A seen_types.add(var.type.ident) 3072307SN/A 3082307SN/A code(''' 3092292SN/A$c_ident * 3102292SN/A${c_ident}Params::create() 3112329SN/A{ 3122329SN/A return new $c_ident(this); 3132292SN/A} 3142329SN/A 3152329SN/A 3162292SN/Aint $c_ident::m_num_controllers = 0; 3172292SN/A 3182292SN/Astringstream ${ident}_transitionComment; 3192292SN/A#define APPEND_TRANSITION_COMMENT(str) (${ident}_transitionComment << str) 3202292SN/A/** \\brief constructor */ 3212329SN/A$c_ident::$c_ident(const Params *p) 3222292SN/A : AbstractController(p) 3232292SN/A{ 3242292SN/A m_version = p->version; 3252292SN/A m_transitions_per_cycle = p->transitions_per_cycle; 3262292SN/A m_buffer_size = p->buffer_size; 3272292SN/A m_recycle_latency = p->recycle_latency; 3282292SN/A m_number_of_TBEs = p->number_of_TBEs; 3292292SN/A''') 3302329SN/A code.indent() 3312329SN/A for param in self.config_parameters: 3322329SN/A code('m_${{param.name}} = p->${{param.name}};') 3332292SN/A 3342292SN/A code('m_num_controllers++;') 3352292SN/A for var in self.objects: 3362292SN/A if var.ident.find("mandatoryQueue") >= 0: 3372292SN/A code('m_${{var.c_ident}}_ptr = new ${{var.type.c_ident}}();') 3382329SN/A 3392292SN/A code.dedent() 3402292SN/A code(''' 3412292SN/A} 3422292SN/A 3432292SN/Avoid $c_ident::init() 3442292SN/A{ 3452292SN/A m_machineID.type = MachineType_${ident}; 3462292SN/A m_machineID.num = m_version; 3472292SN/A 3482292SN/A // Objects 3492292SN/A s_profiler.setVersion(m_version); 3502292SN/A''') 3512292SN/A 3522292SN/A code.indent() 3532292SN/A for var in self.objects: 3542292SN/A vtype = var.type 3552292SN/A vid = "m_%s_ptr" % var.c_ident 3562292SN/A if "network" not in var: 3572292SN/A # Not a network port object 3582292SN/A if "primitive" in vtype: 3592292SN/A code('$vid = new ${{vtype.c_ident}};') 3602292SN/A if "default" in var: 3612292SN/A code('(*$vid) = ${{var["default"]}};') 3622292SN/A else: 3632329SN/A # Normal Object 3642329SN/A # added by SS 3652292SN/A if "factory" in var: 3667720Sgblack@eecs.umich.edu code('$vid = ${{var["factory"]}};') 3677720Sgblack@eecs.umich.edu elif var.ident.find("mandatoryQueue") < 0: 3682292SN/A th = var.get("template_hack", "") 3692292SN/A expr = "%s = new %s%s" % (vid, vtype.c_ident, th) 3702292SN/A 3712292SN/A args = "" 3722292SN/A if "non_obj" not in vtype and not vtype.isEnumeration: 3732292SN/A if expr.find("TBETable") >= 0: 3742292SN/A args = "m_number_of_TBEs" 3752292SN/A else: 3762292SN/A args = var.get("constructor_hack", "") 3772292SN/A args = "(%s)" % args 3782292SN/A 3792292SN/A code('$expr$args;') 3802292SN/A else: 3812292SN/A code(';') 3822292SN/A 3832292SN/A code('assert($vid != NULL);') 3842292SN/A 3852292SN/A if "default" in var: 3862292SN/A code('(*$vid) = ${{var["default"]}}; // Object default') 3872292SN/A elif "default" in vtype: 3882292SN/A code('(*$vid) = ${{vtype["default"]}}; // Type ${{vtype.ident}} default') 3892292SN/A 3902292SN/A # Set ordering 3912292SN/A if "ordered" in var and "trigger_queue" not in var: 3927720Sgblack@eecs.umich.edu # A buffer 3937720Sgblack@eecs.umich.edu code('$vid->setOrdering(${{var["ordered"]}});') 3942292SN/A 3952292SN/A # Set randomization 3962292SN/A if "random" in var: 3972292SN/A # A buffer 3982292SN/A code('$vid->setRandomization(${{var["random"]}});') 3992292SN/A 4002292SN/A # Set Priority 4012292SN/A if vtype.isBuffer and \ 4022292SN/A "rank" in var and "trigger_queue" not in var: 4032292SN/A code('$vid->setPriority(${{var["rank"]}});') 4042292SN/A else: 4052292SN/A # Network port object 4062292SN/A network = var["network"] 4072292SN/A ordered = var["ordered"] 4082292SN/A vnet = var["virtual_network"] 4092292SN/A 4102292SN/A assert var.machine is not None 4112292SN/A code(''' 4122292SN/A$vid = m_net_ptr->get${network}NetQueue(m_version+MachineType_base_number(string_to_MachineType("${{var.machine.ident}}")), $ordered, $vnet); 4132292SN/A''') 4142292SN/A 4152292SN/A code('assert($vid != NULL);') 4162292SN/A 4172292SN/A # Set ordering 4182292SN/A if "ordered" in var: 4192292SN/A # A buffer 4202292SN/A code('$vid->setOrdering(${{var["ordered"]}});') 4212292SN/A 4222292SN/A # Set randomization 4232292SN/A if "random" in var: 4242292SN/A # A buffer 4252292SN/A code('$vid->setRandomization(${{var["random"]}})') 4262292SN/A 4272292SN/A # Set Priority 4282292SN/A if "rank" in var: 4292292SN/A code('$vid->setPriority(${{var["rank"]}})') 4302292SN/A 4312292SN/A # Set buffer size 4322292SN/A if vtype.isBuffer: 4332292SN/A code(''' 4342292SN/Aif (m_buffer_size > 0) { 4352292SN/A $vid->setSize(m_buffer_size); 4362292SN/A} 4372292SN/A''') 4382292SN/A 4392292SN/A # set description (may be overriden later by port def) 4402292SN/A code('$vid->setDescription("[Version " + int_to_string(m_version) + ", ${ident}, name=${{var.c_ident}}]");') 4412292SN/A 4422292SN/A # Set the queue consumers 4432292SN/A code.insert_newline() 4442292SN/A for port in self.in_ports: 4452292SN/A code('${{port.code}}.setConsumer(this);') 4462292SN/A 4472292SN/A # Set the queue descriptions 4482292SN/A code.insert_newline() 4492292SN/A for port in self.in_ports: 4502292SN/A code('${{port.code}}.setDescription("[Version " + int_to_string(m_version) + ", $ident, $port]");') 4518545Ssaidi@eecs.umich.edu 4528545Ssaidi@eecs.umich.edu # Initialize the transition profiling 4538545Ssaidi@eecs.umich.edu code.insert_newline() 4548545Ssaidi@eecs.umich.edu for trans in self.transitions: 4558545Ssaidi@eecs.umich.edu # Figure out if we stall 4568545Ssaidi@eecs.umich.edu stall = False 4578545Ssaidi@eecs.umich.edu for action in trans.actions: 4588545Ssaidi@eecs.umich.edu if action.ident == "z_stall": 4598545Ssaidi@eecs.umich.edu stall = True 4608545Ssaidi@eecs.umich.edu 4618545Ssaidi@eecs.umich.edu # Only possible if it is not a 'z' case 4628545Ssaidi@eecs.umich.edu if not stall: 4638545Ssaidi@eecs.umich.edu state = "%s_State_%s" % (self.ident, trans.state.ident) 4648545Ssaidi@eecs.umich.edu event = "%s_Event_%s" % (self.ident, trans.event.ident) 4658545Ssaidi@eecs.umich.edu code('s_profiler.possibleTransition($state, $event);') 4668545Ssaidi@eecs.umich.edu 4678545Ssaidi@eecs.umich.edu # added by SS to initialize recycle_latency of message buffers 4688545Ssaidi@eecs.umich.edu for buf in self.message_buffer_names: 4698545Ssaidi@eecs.umich.edu code("$buf->setRecycleLatency(m_recycle_latency);") 4708545Ssaidi@eecs.umich.edu 4718545Ssaidi@eecs.umich.edu code.dedent() 4728545Ssaidi@eecs.umich.edu code('}') 4738545Ssaidi@eecs.umich.edu 4748545Ssaidi@eecs.umich.edu has_mandatory_q = False 4758545Ssaidi@eecs.umich.edu for port in self.in_ports: 4768545Ssaidi@eecs.umich.edu if port.code.find("mandatoryQueue_ptr") >= 0: 4778545Ssaidi@eecs.umich.edu has_mandatory_q = True 4788545Ssaidi@eecs.umich.edu 4798545Ssaidi@eecs.umich.edu if has_mandatory_q: 4808545Ssaidi@eecs.umich.edu mq_ident = "m_%s_mandatoryQueue_ptr" % self.ident 4818545Ssaidi@eecs.umich.edu else: 4828545Ssaidi@eecs.umich.edu mq_ident = "NULL" 4838545Ssaidi@eecs.umich.edu 4848545Ssaidi@eecs.umich.edu code(''' 4858545Ssaidi@eecs.umich.eduint $c_ident::getNumControllers() { 4868545Ssaidi@eecs.umich.edu return m_num_controllers; 4878545Ssaidi@eecs.umich.edu} 4888545Ssaidi@eecs.umich.edu 4898545Ssaidi@eecs.umich.eduMessageBuffer* $c_ident::getMandatoryQueue() const { 4908545Ssaidi@eecs.umich.edu return $mq_ident; 4918545Ssaidi@eecs.umich.edu} 4928545Ssaidi@eecs.umich.edu 4938545Ssaidi@eecs.umich.educonst int & $c_ident::getVersion() const{ 4948545Ssaidi@eecs.umich.edu return m_version; 4958545Ssaidi@eecs.umich.edu} 4968545Ssaidi@eecs.umich.edu 4978545Ssaidi@eecs.umich.educonst string $c_ident::toString() const{ 4988545Ssaidi@eecs.umich.edu return "$c_ident"; 4998545Ssaidi@eecs.umich.edu} 5008545Ssaidi@eecs.umich.edu 5018545Ssaidi@eecs.umich.educonst string $c_ident::getName() const{ 5028545Ssaidi@eecs.umich.edu return m_name; 5038545Ssaidi@eecs.umich.edu} 5048545Ssaidi@eecs.umich.educonst MachineType $c_ident::getMachineType() const{ 5052292SN/A return MachineType_${ident}; 5068199SAli.Saidi@ARM.com} 5078199SAli.Saidi@ARM.com 5088199SAli.Saidi@ARM.comvoid $c_ident::blockOnQueue(Address addr, MessageBuffer* port) { 5098199SAli.Saidi@ARM.com m_is_blocking = true; 5108199SAli.Saidi@ARM.com m_block_map[addr] = port; 5118199SAli.Saidi@ARM.com} 5128199SAli.Saidi@ARM.comvoid $c_ident::unblock(Address addr) { 5138199SAli.Saidi@ARM.com m_block_map.erase(addr); 5148199SAli.Saidi@ARM.com if (m_block_map.size() == 0) { 5158199SAli.Saidi@ARM.com m_is_blocking = false; 5168199SAli.Saidi@ARM.com } 5178199SAli.Saidi@ARM.com} 5188199SAli.Saidi@ARM.com 5198199SAli.Saidi@ARM.comvoid $c_ident::print(ostream& out) const { out << "[$c_ident " << m_version << "]"; } 5208199SAli.Saidi@ARM.com 5218199SAli.Saidi@ARM.comvoid $c_ident::printConfig(ostream& out) const { 5228199SAli.Saidi@ARM.com out << "$c_ident config: " << m_name << endl; 5238199SAli.Saidi@ARM.com out << " version: " << m_version << endl; 5248199SAli.Saidi@ARM.com for (map<string, string>::const_iterator it = m_cfg.begin(); it != m_cfg.end(); it++) { 5258199SAli.Saidi@ARM.com out << " " << (*it).first << ": " << (*it).second << endl; 5268199SAli.Saidi@ARM.com } 5278272SAli.Saidi@ARM.com} 5288545Ssaidi@eecs.umich.edu 5298545Ssaidi@eecs.umich.edu// Actions 5308545Ssaidi@eecs.umich.edu''') 5318545Ssaidi@eecs.umich.edu 5328545Ssaidi@eecs.umich.edu for action in self.actions.itervalues(): 5338545Ssaidi@eecs.umich.edu if "c_code" not in action: 5348545Ssaidi@eecs.umich.edu continue 5358545Ssaidi@eecs.umich.edu 5368545Ssaidi@eecs.umich.edu code(''' 5378545Ssaidi@eecs.umich.edu/** \\brief ${{action.desc}} */ 5388545Ssaidi@eecs.umich.eduvoid $c_ident::${{action.ident}}(const Address& addr) 5398199SAli.Saidi@ARM.com{ 5408545Ssaidi@eecs.umich.edu DEBUG_MSG(GENERATED_COMP, HighPrio, "executing"); 5418199SAli.Saidi@ARM.com ${{action["c_code"]}} 5428545Ssaidi@eecs.umich.edu} 5438545Ssaidi@eecs.umich.edu 5448545Ssaidi@eecs.umich.edu''') 5458199SAli.Saidi@ARM.com code.write(path, "%s.cc" % c_ident) 5468545Ssaidi@eecs.umich.edu 5478545Ssaidi@eecs.umich.edu def printCWakeup(self, path): 5488545Ssaidi@eecs.umich.edu '''Output the wakeup loop for the events''' 5498545Ssaidi@eecs.umich.edu 5508545Ssaidi@eecs.umich.edu code = code_formatter() 5518545Ssaidi@eecs.umich.edu ident = self.ident 5528545Ssaidi@eecs.umich.edu 5538545Ssaidi@eecs.umich.edu code(''' 5548545Ssaidi@eecs.umich.edu// Auto generated C++ code started by $__file__:$__line__ 5558545Ssaidi@eecs.umich.edu// ${ident}: ${{self.short}} 5568545Ssaidi@eecs.umich.edu 5578545Ssaidi@eecs.umich.edu#include "mem/ruby/common/Global.hh" 5588545Ssaidi@eecs.umich.edu#include "mem/ruby/slicc_interface/RubySlicc_includes.hh" 5598545Ssaidi@eecs.umich.edu#include "mem/protocol/${ident}_Controller.hh" 5608545Ssaidi@eecs.umich.edu#include "mem/protocol/${ident}_State.hh" 5618545Ssaidi@eecs.umich.edu#include "mem/protocol/${ident}_Event.hh" 5628545Ssaidi@eecs.umich.edu#include "mem/protocol/Types.hh" 5638545Ssaidi@eecs.umich.edu#include "mem/ruby/system/System.hh" 5648545Ssaidi@eecs.umich.edu 5658545Ssaidi@eecs.umich.eduvoid ${ident}_Controller::wakeup() 5668545Ssaidi@eecs.umich.edu{ 5678545Ssaidi@eecs.umich.edu 5688199SAli.Saidi@ARM.com int counter = 0; 5698199SAli.Saidi@ARM.com while (true) { 5708199SAli.Saidi@ARM.com // Some cases will put us into an infinite loop without this limit 5718199SAli.Saidi@ARM.com assert(counter <= m_transitions_per_cycle); 5728199SAli.Saidi@ARM.com if (counter == m_transitions_per_cycle) { 5738199SAli.Saidi@ARM.com g_system_ptr->getProfiler()->controllerBusy(m_machineID); // Count how often we\'re fully utilized 5748199SAli.Saidi@ARM.com g_eventQueue_ptr->scheduleEvent(this, 1); // Wakeup in another cycle and try again 5758199SAli.Saidi@ARM.com break; 5768199SAli.Saidi@ARM.com } 5778199SAli.Saidi@ARM.com''') 5788199SAli.Saidi@ARM.com 5798199SAli.Saidi@ARM.com code.indent() 5802292SN/A code.indent() 5812292SN/A 5824032Sktlim@umich.edu # InPorts 5832292SN/A # 5842292SN/A for port in self.in_ports: 5852292SN/A code.indent() 5867720Sgblack@eecs.umich.edu code('// ${ident}InPort $port') 5877944SGiacomo.Gabrielli@arm.com code('${{port["c_code_in_port"]}}') 5882292SN/A code.dedent() 5894032Sktlim@umich.edu 5904032Sktlim@umich.edu code('') 5912669Sktlim@umich.edu 5922292SN/A code.dedent() 5937944SGiacomo.Gabrielli@arm.com code.dedent() 5947944SGiacomo.Gabrielli@arm.com code(''' 5957944SGiacomo.Gabrielli@arm.com break; // If we got this far, we have nothing left todo 5967944SGiacomo.Gabrielli@arm.com } 5977597Sminkyu.jeong@arm.com} 5987597Sminkyu.jeong@arm.com''') 5997597Sminkyu.jeong@arm.com 6002329SN/A code.write(path, "%s_Wakeup.cc" % self.ident) 6012329SN/A 6022367SN/A def printCSwitch(self, path): 6032367SN/A '''Output switch statement for transition table''' 6047848SAli.Saidi@ARM.com 6057848SAli.Saidi@ARM.com code = code_formatter() 6067600Sminkyu.jeong@arm.com ident = self.ident 6077600Sminkyu.jeong@arm.com 6087600Sminkyu.jeong@arm.com code(''' 6094032Sktlim@umich.edu// Auto generated C++ code started by $__file__:$__line__ 6103731Sktlim@umich.edu// ${ident}: ${{self.short}} 6112367SN/A 6122367SN/A#include "mem/ruby/common/Global.hh" 6132292SN/A#include "mem/protocol/${ident}_Controller.hh" 6142292SN/A#include "mem/protocol/${ident}_State.hh" 6154032Sktlim@umich.edu#include "mem/protocol/${ident}_Event.hh" 6164032Sktlim@umich.edu#include "mem/protocol/Types.hh" 6174032Sktlim@umich.edu#include "mem/ruby/system/System.hh" 6184032Sktlim@umich.edu 6194032Sktlim@umich.edu#define HASH_FUN(state, event) ((int(state)*${ident}_Event_NUM)+int(event)) 6208199SAli.Saidi@ARM.com 6218199SAli.Saidi@ARM.com#define GET_TRANSITION_COMMENT() (${ident}_transitionComment.str()) 6222292SN/A#define CLEAR_TRANSITION_COMMENT() (${ident}_transitionComment.str("")) 6232292SN/A 6242292SN/ATransitionResult ${ident}_Controller::doTransition(${ident}_Event event, ${ident}_State state, const Address& addr 6252292SN/A) 6262292SN/A{ 6272292SN/A ${ident}_State next_state = state; 6282292SN/A 6292292SN/A DEBUG_NEWLINE(GENERATED_COMP, MedPrio); 6302292SN/A DEBUG_MSG(GENERATED_COMP, MedPrio, *this); 6312292SN/A DEBUG_EXPR(GENERATED_COMP, MedPrio, g_eventQueue_ptr->getTime()); 6322292SN/A DEBUG_EXPR(GENERATED_COMP, MedPrio,state); 6332292SN/A DEBUG_EXPR(GENERATED_COMP, MedPrio,event); 6342292SN/A DEBUG_EXPR(GENERATED_COMP, MedPrio,addr); 6352292SN/A 6362292SN/A TransitionResult result = doTransitionWorker(event, state, next_state, addr); 6377720Sgblack@eecs.umich.edu 6387720Sgblack@eecs.umich.edu if (result == TransitionResult_Valid) { 6392292SN/A DEBUG_EXPR(GENERATED_COMP, MedPrio, next_state); 6404032Sktlim@umich.edu DEBUG_NEWLINE(GENERATED_COMP, MedPrio); 6414032Sktlim@umich.edu s_profiler.countTransition(state, event); 6422292SN/A if (Debug::getProtocolTrace()) { 6432292SN/A g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr, 6442292SN/A ${ident}_State_to_string(state), 6452292SN/A ${ident}_Event_to_string(event), 6462292SN/A ${ident}_State_to_string(next_state), GET_TRANSITION_COMMENT()); 6472292SN/A } 6487944SGiacomo.Gabrielli@arm.com CLEAR_TRANSITION_COMMENT(); 6497944SGiacomo.Gabrielli@arm.com ${ident}_setState(addr, next_state); 6507944SGiacomo.Gabrielli@arm.com 6517944SGiacomo.Gabrielli@arm.com } else if (result == TransitionResult_ResourceStall) { 6527848SAli.Saidi@ARM.com if (Debug::getProtocolTrace()) { 6537848SAli.Saidi@ARM.com g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr, 6547848SAli.Saidi@ARM.com ${ident}_State_to_string(state), 6552329SN/A ${ident}_Event_to_string(event), 6567782Sminkyu.jeong@arm.com ${ident}_State_to_string(next_state), 6577720Sgblack@eecs.umich.edu "Resource Stall"); 6582292SN/A } 6592292SN/A } else if (result == TransitionResult_ProtocolStall) { 6607782Sminkyu.jeong@arm.com DEBUG_MSG(GENERATED_COMP, HighPrio, "stalling"); 6617782Sminkyu.jeong@arm.com DEBUG_NEWLINE(GENERATED_COMP, MedPrio); 6627782Sminkyu.jeong@arm.com if (Debug::getProtocolTrace()) { 6637782Sminkyu.jeong@arm.com g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr, 6642292SN/A ${ident}_State_to_string(state), 6652292SN/A ${ident}_Event_to_string(event), 6662292SN/A ${ident}_State_to_string(next_state), 6672292SN/A "Protocol Stall"); 6682336SN/A } 6692336SN/A } 6702336SN/A 6712329SN/A return result; 6722292SN/A} 6732329SN/A 6742292SN/ATransitionResult ${ident}_Controller::doTransitionWorker(${ident}_Event event, ${ident}_State state, ${ident}_State& next_state, const Address& addr 6752292SN/A) 6768199SAli.Saidi@ARM.com{ 6772292SN/A switch(HASH_FUN(state, event)) { 6782292SN/A''') 6792292SN/A 6802292SN/A # This map will allow suppress generating duplicate code 6812292SN/A cases = orderdict() 6822292SN/A 6832292SN/A for trans in self.transitions: 6842292SN/A case_string = "%s_State_%s, %s_Event_%s" % \ 6852292SN/A (self.ident, trans.state.ident, self.ident, trans.event.ident) 6867720Sgblack@eecs.umich.edu 6877720Sgblack@eecs.umich.edu case = code_formatter() 6882292SN/A # Only set next_state if it changes 6892292SN/A if trans.state != trans.nextState: 6902292SN/A ns_ident = trans.nextState.ident 6912292SN/A case('next_state = ${ident}_State_${ns_ident};') 6922292SN/A 6932292SN/A actions = trans.actions 6942292SN/A 6952292SN/A # Check for resources 6962292SN/A case_sorter = [] 6972292SN/A res = trans.resources 6982292SN/A for key,val in res.iteritems(): 6992292SN/A if key.type.ident != "DNUCAStopTable": 7002292SN/A val = ''' 7012292SN/Aif (!%s.areNSlotsAvailable(%s)) { 7022292SN/A return TransitionResult_ResourceStall; 7032292SN/A} 7042292SN/A''' % (key.code, val) 7052292SN/A case_sorter.append(val) 7062292SN/A 7072292SN/A 7082292SN/A # Emit the code sequences in a sorted order. This makes the 7092292SN/A # output deterministic (without this the output order can vary 7102292SN/A # since Map's keys() on a vector of pointers is not deterministic 7112292SN/A for c in sorted(case_sorter): 7122292SN/A case("$c") 7132292SN/A 7142292SN/A # Figure out if we stall 7152292SN/A stall = False 7162292SN/A for action in actions: 7172329SN/A if action.ident == "z_stall": 7182329SN/A stall = True 7192292SN/A break 7202292SN/A 7212292SN/A if stall: 7222292SN/A case('return TransitionResult_ProtocolStall;') 7232292SN/A else: 7247720Sgblack@eecs.umich.edu for action in actions: 7257720Sgblack@eecs.umich.edu case('${{action.ident}}(addr);') 7262292SN/A case('return TransitionResult_Valid;') 7272292SN/A 7282292SN/A case = str(case) 7292292SN/A 7302292SN/A # Look to see if this transition code is unique. 7312292SN/A if case not in cases: 7322292SN/A cases[case] = [] 7332292SN/A 7342292SN/A cases[case].append(case_string) 7352292SN/A 7362292SN/A # Walk through all of the unique code blocks and spit out the 7372292SN/A # corresponding case statement elements 7382292SN/A for case,transitions in cases.iteritems(): 7396974Stjones1@inf.ed.ac.uk # Iterative over all the multiple transitions that share 7406974Stjones1@inf.ed.ac.uk # the same code 7416974Stjones1@inf.ed.ac.uk for trans in transitions: 7426974Stjones1@inf.ed.ac.uk code(' case HASH_FUN($trans):') 7436974Stjones1@inf.ed.ac.uk code(' {') 7446974Stjones1@inf.ed.ac.uk code(' $case') 7456974Stjones1@inf.ed.ac.uk code(' }') 7466974Stjones1@inf.ed.ac.uk 7476974Stjones1@inf.ed.ac.uk code(''' 7486974Stjones1@inf.ed.ac.uk default: 7496974Stjones1@inf.ed.ac.uk WARN_EXPR(m_version); 7506974Stjones1@inf.ed.ac.uk WARN_EXPR(g_eventQueue_ptr->getTime()); 7516974Stjones1@inf.ed.ac.uk WARN_EXPR(addr); 7526974Stjones1@inf.ed.ac.uk WARN_EXPR(event); 7536974Stjones1@inf.ed.ac.uk WARN_EXPR(state); 7546974Stjones1@inf.ed.ac.uk ERROR_MSG(\"Invalid transition\"); 7552292SN/A } 7562292SN/A return TransitionResult_Valid; 7576974Stjones1@inf.ed.ac.uk} 7586974Stjones1@inf.ed.ac.uk''') 7596974Stjones1@inf.ed.ac.uk code.write(path, "%s_Transitions.cc" % self.ident) 7606974Stjones1@inf.ed.ac.uk 7616974Stjones1@inf.ed.ac.uk def printProfilerHH(self, path): 7626974Stjones1@inf.ed.ac.uk code = code_formatter() 7632292SN/A ident = self.ident 7642292SN/A 7652292SN/A code(''' 7662292SN/A// Auto generated C++ code started by $__file__:$__line__ 7672292SN/A// ${ident}: ${{self.short}} 7682292SN/A 7692907Sktlim@umich.edu#ifndef ${ident}_PROFILER_H 7702678Sktlim@umich.edu#define ${ident}_PROFILER_H 7712678Sktlim@umich.edu 7722678Sktlim@umich.edu#include "mem/ruby/common/Global.hh" 7732678Sktlim@umich.edu#include "mem/protocol/${ident}_State.hh" 7742678Sktlim@umich.edu#include "mem/protocol/${ident}_Event.hh" 7752329SN/A 7762329SN/Aclass ${ident}_Profiler { 7772292SN/A public: 7782292SN/A ${ident}_Profiler(); 7792292SN/A void setVersion(int version); 7802292SN/A void countTransition(${ident}_State state, ${ident}_Event event); 7812292SN/A void possibleTransition(${ident}_State state, ${ident}_Event event); 7822292SN/A void dumpStats(ostream& out) const; 7832292SN/A void clearStats(); 7842678Sktlim@umich.edu 7852292SN/A private: 7862292SN/A int m_counters[${ident}_State_NUM][${ident}_Event_NUM]; 7872292SN/A int m_event_counters[${ident}_Event_NUM]; 7882292SN/A bool m_possible[${ident}_State_NUM][${ident}_Event_NUM]; 7892292SN/A int m_version; 7902292SN/A}; 7912292SN/A 7922292SN/A#endif // ${ident}_PROFILER_H 7932292SN/A''') 7942292SN/A code.write(path, "%s_Profiler.hh" % self.ident) 7952292SN/A 7966974Stjones1@inf.ed.ac.uk def printProfilerCC(self, path): 7976974Stjones1@inf.ed.ac.uk code = code_formatter() 7986974Stjones1@inf.ed.ac.uk ident = self.ident 7996974Stjones1@inf.ed.ac.uk 8006974Stjones1@inf.ed.ac.uk code(''' 8012669Sktlim@umich.edu// Auto generated C++ code started by $__file__:$__line__ 8022669Sktlim@umich.edu// ${ident}: ${{self.short}} 8032669Sktlim@umich.edu 8048481Sgblack@eecs.umich.edu#include "mem/protocol/${ident}_Profiler.hh" 8058481Sgblack@eecs.umich.edu 8068481Sgblack@eecs.umich.edu${ident}_Profiler::${ident}_Profiler() 8072292SN/A{ 8082292SN/A for (int state = 0; state < ${ident}_State_NUM; state++) { 8092669Sktlim@umich.edu for (int event = 0; event < ${ident}_Event_NUM; event++) { 8102669Sktlim@umich.edu m_possible[state][event] = false; 8113772Sgblack@eecs.umich.edu m_counters[state][event] = 0; 8124326Sgblack@eecs.umich.edu } 8132669Sktlim@umich.edu } 8144878Sstever@eecs.umich.edu for (int event = 0; event < ${ident}_Event_NUM; event++) { 8154878Sstever@eecs.umich.edu m_event_counters[event] = 0; 8166102Sgblack@eecs.umich.edu } 8176974Stjones1@inf.ed.ac.uk} 8186974Stjones1@inf.ed.ac.ukvoid ${ident}_Profiler::setVersion(int version) 8192292SN/A{ 8202678Sktlim@umich.edu m_version = version; 8212678Sktlim@umich.edu} 8222678Sktlim@umich.eduvoid ${ident}_Profiler::clearStats() 8232678Sktlim@umich.edu{ 8246974Stjones1@inf.ed.ac.uk for (int state = 0; state < ${ident}_State_NUM; state++) { 8256974Stjones1@inf.ed.ac.uk for (int event = 0; event < ${ident}_Event_NUM; event++) { 8266974Stjones1@inf.ed.ac.uk m_counters[state][event] = 0; 8276974Stjones1@inf.ed.ac.uk } 8286974Stjones1@inf.ed.ac.uk } 8296974Stjones1@inf.ed.ac.uk 8306974Stjones1@inf.ed.ac.uk for (int event = 0; event < ${ident}_Event_NUM; event++) { 8316974Stjones1@inf.ed.ac.uk m_event_counters[event] = 0; 8326974Stjones1@inf.ed.ac.uk } 8336974Stjones1@inf.ed.ac.uk} 8346974Stjones1@inf.ed.ac.ukvoid ${ident}_Profiler::countTransition(${ident}_State state, ${ident}_Event event) 8356974Stjones1@inf.ed.ac.uk{ 8366974Stjones1@inf.ed.ac.uk assert(m_possible[state][event]); 8376974Stjones1@inf.ed.ac.uk m_counters[state][event]++; 8386974Stjones1@inf.ed.ac.uk m_event_counters[event]++; 8396974Stjones1@inf.ed.ac.uk} 8406974Stjones1@inf.ed.ac.ukvoid ${ident}_Profiler::possibleTransition(${ident}_State state, ${ident}_Event event) 8416974Stjones1@inf.ed.ac.uk{ 8426974Stjones1@inf.ed.ac.uk m_possible[state][event] = true; 8436974Stjones1@inf.ed.ac.uk} 8446974Stjones1@inf.ed.ac.ukvoid ${ident}_Profiler::dumpStats(ostream& out) const 8456974Stjones1@inf.ed.ac.uk{ 8466974Stjones1@inf.ed.ac.uk out << " --- ${ident} " << m_version << " ---" << endl; 8476974Stjones1@inf.ed.ac.uk out << " - Event Counts -" << endl; 8486974Stjones1@inf.ed.ac.uk for (int event = 0; event < ${ident}_Event_NUM; event++) { 8492678Sktlim@umich.edu int count = m_event_counters[event]; 8507720Sgblack@eecs.umich.edu out << (${ident}_Event) event << " " << count << endl; 8512292SN/A } 8527720Sgblack@eecs.umich.edu out << endl; 8533797Sgblack@eecs.umich.edu out << " - Transitions -" << endl; 8543221Sktlim@umich.edu for (int state = 0; state < ${ident}_State_NUM; state++) { 8552292SN/A for (int event = 0; event < ${ident}_Event_NUM; event++) { 8562693Sktlim@umich.edu if (m_possible[state][event]) { 8574350Sgblack@eecs.umich.edu int count = m_counters[state][event]; 8586974Stjones1@inf.ed.ac.uk out << (${ident}_State) state << " " << (${ident}_Event) event << " " << count; 8593326Sktlim@umich.edu if (count == 0) { 8603326Sktlim@umich.edu out << " <-- "; 8613326Sktlim@umich.edu } 8623326Sktlim@umich.edu out << endl; 8633326Sktlim@umich.edu } 8643326Sktlim@umich.edu } 8653326Sktlim@umich.edu out << endl; 8663326Sktlim@umich.edu } 8673326Sktlim@umich.edu} 8683326Sktlim@umich.edu''') 8693326Sktlim@umich.edu code.write(path, "%s_Profiler.cc" % self.ident) 8703326Sktlim@umich.edu 8713326Sktlim@umich.edu # ************************** 8727823Ssteve.reinhardt@amd.com # ******* HTML Files ******* 8733326Sktlim@umich.edu # ************************** 8743326Sktlim@umich.edu def frameRef(self, click_href, click_target, over_href, over_target_num, 8753326Sktlim@umich.edu text): 8762693Sktlim@umich.edu code = code_formatter(fix_newlines=False) 8772693Sktlim@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>""") 8782693Sktlim@umich.edu return str(code) 8792693Sktlim@umich.edu 8802693Sktlim@umich.edu def writeHTMLFiles(self, path): 8812693Sktlim@umich.edu # Create table with no row hilighted 8828481Sgblack@eecs.umich.edu self.printHTMLTransitions(path, None) 8838481Sgblack@eecs.umich.edu 8848481Sgblack@eecs.umich.edu # Generate transition tables 8858481Sgblack@eecs.umich.edu for state in self.states.itervalues(): 8868481Sgblack@eecs.umich.edu self.printHTMLTransitions(path, state) 8878481Sgblack@eecs.umich.edu 8888481Sgblack@eecs.umich.edu # Generate action descriptions 8898481Sgblack@eecs.umich.edu for action in self.actions.itervalues(): 8908481Sgblack@eecs.umich.edu name = "%s_action_%s.html" % (self.ident, action.ident) 8918481Sgblack@eecs.umich.edu code = html.createSymbol(action, "Action") 8928481Sgblack@eecs.umich.edu code.write(path, name) 8938481Sgblack@eecs.umich.edu 8948481Sgblack@eecs.umich.edu # Generate state descriptions 8958481Sgblack@eecs.umich.edu for state in self.states.itervalues(): 8968481Sgblack@eecs.umich.edu name = "%s_State_%s.html" % (self.ident, state.ident) 8978481Sgblack@eecs.umich.edu code = html.createSymbol(state, "State") 8988481Sgblack@eecs.umich.edu code.write(path, name) 8998481Sgblack@eecs.umich.edu 9008481Sgblack@eecs.umich.edu # Generate event descriptions 9018481Sgblack@eecs.umich.edu for event in self.events.itervalues(): 9028481Sgblack@eecs.umich.edu name = "%s_Event_%s.html" % (self.ident, event.ident) 9034032Sktlim@umich.edu code = html.createSymbol(event, "Event") 9043221Sktlim@umich.edu code.write(path, name) 9053221Sktlim@umich.edu 9066974Stjones1@inf.ed.ac.uk def printHTMLTransitions(self, path, active_state): 9076974Stjones1@inf.ed.ac.uk code = code_formatter() 9088481Sgblack@eecs.umich.edu 9096974Stjones1@inf.ed.ac.uk code(''' 9106974Stjones1@inf.ed.ac.uk<HTML><BODY link="blue" vlink="blue"> 9116974Stjones1@inf.ed.ac.uk 9122669Sktlim@umich.edu<H1 align="center">${{html.formatShorthand(self.short)}}: 9136974Stjones1@inf.ed.ac.uk''') 9146974Stjones1@inf.ed.ac.uk code.indent() 9158481Sgblack@eecs.umich.edu for i,machine in enumerate(self.symtab.getAllType(StateMachine)): 9166974Stjones1@inf.ed.ac.uk mid = machine.ident 9176974Stjones1@inf.ed.ac.uk if i != 0: 9186974Stjones1@inf.ed.ac.uk extra = " - " 9196974Stjones1@inf.ed.ac.uk else: 9206974Stjones1@inf.ed.ac.uk extra = "" 9216974Stjones1@inf.ed.ac.uk if machine == self: 9226974Stjones1@inf.ed.ac.uk code('$extra$mid') 9236974Stjones1@inf.ed.ac.uk else: 9246974Stjones1@inf.ed.ac.uk code('$extra<A target="Table" href="${mid}_table.html">$mid</A>') 9256974Stjones1@inf.ed.ac.uk code.dedent() 9266974Stjones1@inf.ed.ac.uk 9276974Stjones1@inf.ed.ac.uk code(""" 9286974Stjones1@inf.ed.ac.uk</H1> 9296974Stjones1@inf.ed.ac.uk 9306974Stjones1@inf.ed.ac.uk<TABLE border=1> 9316974Stjones1@inf.ed.ac.uk<TR> 9326974Stjones1@inf.ed.ac.uk <TH> </TH> 9336974Stjones1@inf.ed.ac.uk""") 9346974Stjones1@inf.ed.ac.uk 9356974Stjones1@inf.ed.ac.uk for event in self.events.itervalues(): 9366974Stjones1@inf.ed.ac.uk href = "%s_Event_%s.html" % (self.ident, event.ident) 9376974Stjones1@inf.ed.ac.uk ref = self.frameRef(href, "Status", href, "1", event.short) 9386974Stjones1@inf.ed.ac.uk code('<TH bgcolor=white>$ref</TH>') 9396974Stjones1@inf.ed.ac.uk 9402292SN/A code('</TR>') 9412292SN/A # -- Body of table 9422292SN/A for state in self.states.itervalues(): 9432292SN/A # -- Each row 9442292SN/A if state == active_state: 9452292SN/A color = "yellow" 9462292SN/A else: 9472292SN/A color = "white" 9482292SN/A 9492292SN/A click = "%s_table_%s.html" % (self.ident, state.ident) 9502292SN/A over = "%s_State_%s.html" % (self.ident, state.ident) 9512292SN/A text = html.formatShorthand(state.short) 9522292SN/A ref = self.frameRef(click, "Table", over, "1", state.short) 9532292SN/A code(''' 9542292SN/A<TR> 9552292SN/A <TH bgcolor=$color>$ref</TH> 9562292SN/A''') 9572292SN/A 9582292SN/A # -- One column for each event 9592292SN/A for event in self.events.itervalues(): 9602292SN/A trans = self.table.get((state,event), None) 9612292SN/A if trans is None: 9622292SN/A # This is the no transition case 9632292SN/A if state == active_state: 9642292SN/A color = "#C0C000" 9652292SN/A else: 9662292SN/A color = "lightgrey" 9672292SN/A 9682329SN/A code('<TD bgcolor=$color> </TD>') 9692292SN/A continue 9702292SN/A 9712292SN/A next = trans.nextState 9722292SN/A stall_action = False 9732292SN/A 9747720Sgblack@eecs.umich.edu # -- Get the actions 9752292SN/A for action in trans.actions: 9767720Sgblack@eecs.umich.edu if action.ident == "z_stall" or \ 9772292SN/A action.ident == "zz_recycleMandatoryQueue": 9782292SN/A stall_action = True 9792292SN/A 9802292SN/A # -- Print out "actions/next-state" 9812292SN/A if stall_action: 9822292SN/A if state == active_state: 9832292SN/A color = "#C0C000" 9842292SN/A else: 9852329SN/A color = "lightgrey" 9862731Sktlim@umich.edu 9872292SN/A elif active_state and next.ident == active_state.ident: 9882292SN/A color = "aqua" 9892292SN/A elif state == active_state: 9902292SN/A color = "yellow" 9912292SN/A else: 9922292SN/A color = "white" 9932292SN/A 9942727Sktlim@umich.edu fix = code.nofix() 9952292SN/A code('<TD bgcolor=$color>') 9962292SN/A for action in trans.actions: 9972292SN/A href = "%s_action_%s.html" % (self.ident, action.ident) 9982292SN/A ref = self.frameRef(href, "Status", href, "1", 9992292SN/A action.short) 10002292SN/A code(' $ref\n') 10012292SN/A if next != state: 10022292SN/A if trans.actions: 10032292SN/A code('/') 10042292SN/A click = "%s_table_%s.html" % (self.ident, next.ident) 10054032Sktlim@umich.edu over = "%s_State_%s.html" % (self.ident, next.ident) 10064032Sktlim@umich.edu ref = self.frameRef(click, "Table", over, "1", next.short) 10074032Sktlim@umich.edu code("$ref") 10084032Sktlim@umich.edu code("</TD>\n") 10092292SN/A code.fix(fix) 10102292SN/A 10112292SN/A # -- Each row 10122292SN/A if state == active_state: 10132292SN/A color = "yellow" 10142329SN/A else: 10152292SN/A color = "white" 10162292SN/A 10172292SN/A click = "%s_table_%s.html" % (self.ident, state.ident) 10182292SN/A over = "%s_State_%s.html" % (self.ident, state.ident) 10197720Sgblack@eecs.umich.edu ref = self.frameRef(click, "Table", over, "1", state.short) 10202292SN/A code(''' 10217720Sgblack@eecs.umich.edu <TH bgcolor=$color>$ref</TH> 10222292SN/A</TR> 10232292SN/A''') 10242329SN/A code(''' 10252329SN/A<TR> 10262292SN/A <TH> </TH> 10272292SN/A''') 10282292SN/A 10292292SN/A for event in self.events.itervalues(): 10302292SN/A href = "%s_Event_%s.html" % (self.ident, event.ident) 10312292SN/A ref = self.frameRef(href, "Status", href, "1", event.short) 10322292SN/A code('<TH bgcolor=white>$ref</TH>') 10332329SN/A code(''' 10342731Sktlim@umich.edu</TR> 10352292SN/A</TABLE> 10362292SN/A</BODY></HTML> 10372292SN/A''') 10384032Sktlim@umich.edu 10394032Sktlim@umich.edu 10404032Sktlim@umich.edu if active_state: 10414032Sktlim@umich.edu name = "%s_table_%s.html" % (self.ident, active_state.ident) 10426974Stjones1@inf.ed.ac.uk else: 10436974Stjones1@inf.ed.ac.uk name = "%s_table.html" % self.ident 10446974Stjones1@inf.ed.ac.uk code.write(path, name) 10456974Stjones1@inf.ed.ac.uk 10466974Stjones1@inf.ed.ac.uk__all__ = [ "StateMachine" ] 10476974Stjones1@inf.ed.ac.uk