StateMachine.py revision 11049
16657Snate@binkert.org# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 26657Snate@binkert.org# Copyright (c) 2009 The Hewlett-Packard Development Company 310972Sdavid.hashe@amd.com# Copyright (c) 2013 Advanced Micro Devices, Inc. 46657Snate@binkert.org# All rights reserved. 56657Snate@binkert.org# 66657Snate@binkert.org# Redistribution and use in source and binary forms, with or without 76657Snate@binkert.org# modification, are permitted provided that the following conditions are 86657Snate@binkert.org# met: redistributions of source code must retain the above copyright 96657Snate@binkert.org# notice, this list of conditions and the following disclaimer; 106657Snate@binkert.org# redistributions in binary form must reproduce the above copyright 116657Snate@binkert.org# notice, this list of conditions and the following disclaimer in the 126657Snate@binkert.org# documentation and/or other materials provided with the distribution; 136657Snate@binkert.org# neither the name of the copyright holders nor the names of its 146657Snate@binkert.org# contributors may be used to endorse or promote products derived from 156657Snate@binkert.org# this software without specific prior written permission. 166657Snate@binkert.org# 176657Snate@binkert.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 186657Snate@binkert.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 196657Snate@binkert.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 206657Snate@binkert.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 216657Snate@binkert.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 226657Snate@binkert.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 236657Snate@binkert.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 246657Snate@binkert.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 256657Snate@binkert.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 266657Snate@binkert.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 276657Snate@binkert.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 286657Snate@binkert.org 296999Snate@binkert.orgfrom m5.util import orderdict 306657Snate@binkert.org 316657Snate@binkert.orgfrom slicc.symbols.Symbol import Symbol 326657Snate@binkert.orgfrom slicc.symbols.Var import Var 336657Snate@binkert.orgimport slicc.generate.html as html 348189SLisa.Hsu@amd.comimport re 356657Snate@binkert.org 369499Snilay@cs.wisc.edupython_class_map = { 379499Snilay@cs.wisc.edu "int": "Int", 389364Snilay@cs.wisc.edu "uint32_t" : "UInt32", 397055Snate@binkert.org "std::string": "String", 406882SBrad.Beckmann@amd.com "bool": "Bool", 416882SBrad.Beckmann@amd.com "CacheMemory": "RubyCache", 428191SLisa.Hsu@amd.com "WireBuffer": "RubyWireBuffer", 436882SBrad.Beckmann@amd.com "Sequencer": "RubySequencer", 446882SBrad.Beckmann@amd.com "DirectoryMemory": "RubyDirectoryMemory", 459102SNuwan.Jayasena@amd.com "MemoryControl": "MemoryControl", 469366Snilay@cs.wisc.edu "DMASequencer": "DMASequencer", 479499Snilay@cs.wisc.edu "Prefetcher":"Prefetcher", 489499Snilay@cs.wisc.edu "Cycles":"Cycles", 499499Snilay@cs.wisc.edu } 506882SBrad.Beckmann@amd.com 516657Snate@binkert.orgclass StateMachine(Symbol): 526657Snate@binkert.org def __init__(self, symtab, ident, location, pairs, config_parameters): 536657Snate@binkert.org super(StateMachine, self).__init__(symtab, ident, location, pairs) 546657Snate@binkert.org self.table = None 5510311Snilay@cs.wisc.edu 5610311Snilay@cs.wisc.edu # Data members in the State Machine that have been declared before 5710311Snilay@cs.wisc.edu # the opening brace '{' of the machine. Note that these along with 5810311Snilay@cs.wisc.edu # the members in self.objects form the entire set of data members. 596657Snate@binkert.org self.config_parameters = config_parameters 6010311Snilay@cs.wisc.edu 619366Snilay@cs.wisc.edu self.prefetchers = [] 627839Snilay@cs.wisc.edu 636657Snate@binkert.org for param in config_parameters: 646882SBrad.Beckmann@amd.com if param.pointer: 6510308Snilay@cs.wisc.edu var = Var(symtab, param.ident, location, param.type_ast.type, 6610308Snilay@cs.wisc.edu "(*m_%s_ptr)" % param.ident, {}, self) 676882SBrad.Beckmann@amd.com else: 6810308Snilay@cs.wisc.edu var = Var(symtab, param.ident, location, param.type_ast.type, 6910308Snilay@cs.wisc.edu "m_%s" % param.ident, {}, self) 7010308Snilay@cs.wisc.edu 7110308Snilay@cs.wisc.edu self.symtab.registerSym(param.ident, var) 7210308Snilay@cs.wisc.edu 739366Snilay@cs.wisc.edu if str(param.type_ast.type) == "Prefetcher": 749366Snilay@cs.wisc.edu self.prefetchers.append(var) 756657Snate@binkert.org 766657Snate@binkert.org self.states = orderdict() 776657Snate@binkert.org self.events = orderdict() 786657Snate@binkert.org self.actions = orderdict() 799104Shestness@cs.utexas.edu self.request_types = orderdict() 806657Snate@binkert.org self.transitions = [] 816657Snate@binkert.org self.in_ports = [] 826657Snate@binkert.org self.functions = [] 8310311Snilay@cs.wisc.edu 8410311Snilay@cs.wisc.edu # Data members in the State Machine that have been declared inside 8510311Snilay@cs.wisc.edu # the {} machine. Note that these along with the config params 8610311Snilay@cs.wisc.edu # form the entire set of data members of the machine. 876657Snate@binkert.org self.objects = [] 887839Snilay@cs.wisc.edu self.TBEType = None 897839Snilay@cs.wisc.edu self.EntryType = None 9010972Sdavid.hashe@amd.com self.debug_flags = set() 9110972Sdavid.hashe@amd.com self.debug_flags.add('RubyGenerated') 9210972Sdavid.hashe@amd.com self.debug_flags.add('RubySlicc') 936657Snate@binkert.org 946657Snate@binkert.org def __repr__(self): 956657Snate@binkert.org return "[StateMachine: %s]" % self.ident 966657Snate@binkert.org 976657Snate@binkert.org def addState(self, state): 986657Snate@binkert.org assert self.table is None 996657Snate@binkert.org self.states[state.ident] = state 1006657Snate@binkert.org 1016657Snate@binkert.org def addEvent(self, event): 1026657Snate@binkert.org assert self.table is None 1036657Snate@binkert.org self.events[event.ident] = event 1046657Snate@binkert.org 1056657Snate@binkert.org def addAction(self, action): 1066657Snate@binkert.org assert self.table is None 1076657Snate@binkert.org 1086657Snate@binkert.org # Check for duplicate action 1096657Snate@binkert.org for other in self.actions.itervalues(): 1106657Snate@binkert.org if action.ident == other.ident: 1116779SBrad.Beckmann@amd.com action.warning("Duplicate action definition: %s" % action.ident) 1126657Snate@binkert.org action.error("Duplicate action definition: %s" % action.ident) 1136657Snate@binkert.org if action.short == other.short: 1146657Snate@binkert.org other.warning("Duplicate action shorthand: %s" % other.ident) 1156657Snate@binkert.org other.warning(" shorthand = %s" % other.short) 1166657Snate@binkert.org action.warning("Duplicate action shorthand: %s" % action.ident) 1176657Snate@binkert.org action.error(" shorthand = %s" % action.short) 1186657Snate@binkert.org 1196657Snate@binkert.org self.actions[action.ident] = action 1206657Snate@binkert.org 12110972Sdavid.hashe@amd.com def addDebugFlag(self, flag): 12210972Sdavid.hashe@amd.com self.debug_flags.add(flag) 12310972Sdavid.hashe@amd.com 1249104Shestness@cs.utexas.edu def addRequestType(self, request_type): 1259104Shestness@cs.utexas.edu assert self.table is None 1269104Shestness@cs.utexas.edu self.request_types[request_type.ident] = request_type 1279104Shestness@cs.utexas.edu 1286657Snate@binkert.org def addTransition(self, trans): 1296657Snate@binkert.org assert self.table is None 1306657Snate@binkert.org self.transitions.append(trans) 1316657Snate@binkert.org 1326657Snate@binkert.org def addInPort(self, var): 1336657Snate@binkert.org self.in_ports.append(var) 1346657Snate@binkert.org 1356657Snate@binkert.org def addFunc(self, func): 1366657Snate@binkert.org # register func in the symbol table 1376657Snate@binkert.org self.symtab.registerSym(str(func), func) 1386657Snate@binkert.org self.functions.append(func) 1396657Snate@binkert.org 1406657Snate@binkert.org def addObject(self, obj): 14110307Snilay@cs.wisc.edu self.symtab.registerSym(str(obj), obj) 1426657Snate@binkert.org self.objects.append(obj) 1436657Snate@binkert.org 1447839Snilay@cs.wisc.edu def addType(self, type): 1457839Snilay@cs.wisc.edu type_ident = '%s' % type.c_ident 1467839Snilay@cs.wisc.edu 1477839Snilay@cs.wisc.edu if type_ident == "%s_TBE" %self.ident: 1487839Snilay@cs.wisc.edu if self.TBEType != None: 1497839Snilay@cs.wisc.edu self.error("Multiple Transaction Buffer types in a " \ 1507839Snilay@cs.wisc.edu "single machine."); 1517839Snilay@cs.wisc.edu self.TBEType = type 1527839Snilay@cs.wisc.edu 1537839Snilay@cs.wisc.edu elif "interface" in type and "AbstractCacheEntry" == type["interface"]: 15410968Sdavid.hashe@amd.com if "main" in type and "false" == type["main"].lower(): 15510968Sdavid.hashe@amd.com pass # this isn't the EntryType 15610968Sdavid.hashe@amd.com else: 15710968Sdavid.hashe@amd.com if self.EntryType != None: 15810968Sdavid.hashe@amd.com self.error("Multiple AbstractCacheEntry types in a " \ 15910968Sdavid.hashe@amd.com "single machine."); 16010968Sdavid.hashe@amd.com self.EntryType = type 1617839Snilay@cs.wisc.edu 1626657Snate@binkert.org # Needs to be called before accessing the table 1636657Snate@binkert.org def buildTable(self): 1646657Snate@binkert.org assert self.table is None 1656657Snate@binkert.org 1666657Snate@binkert.org table = {} 1676657Snate@binkert.org 1686657Snate@binkert.org for trans in self.transitions: 1696657Snate@binkert.org # Track which actions we touch so we know if we use them 1706657Snate@binkert.org # all -- really this should be done for all symbols as 1716657Snate@binkert.org # part of the symbol table, then only trigger it for 1726657Snate@binkert.org # Actions, States, Events, etc. 1736657Snate@binkert.org 1746657Snate@binkert.org for action in trans.actions: 1756657Snate@binkert.org action.used = True 1766657Snate@binkert.org 1776657Snate@binkert.org index = (trans.state, trans.event) 1786657Snate@binkert.org if index in table: 1796657Snate@binkert.org table[index].warning("Duplicate transition: %s" % table[index]) 1806657Snate@binkert.org trans.error("Duplicate transition: %s" % trans) 1816657Snate@binkert.org table[index] = trans 1826657Snate@binkert.org 1836657Snate@binkert.org # Look at all actions to make sure we used them all 1846657Snate@binkert.org for action in self.actions.itervalues(): 1856657Snate@binkert.org if not action.used: 1866657Snate@binkert.org error_msg = "Unused action: %s" % action.ident 1876657Snate@binkert.org if "desc" in action: 1886657Snate@binkert.org error_msg += ", " + action.desc 1896657Snate@binkert.org action.warning(error_msg) 1906657Snate@binkert.org self.table = table 1916657Snate@binkert.org 19210963Sdavid.hashe@amd.com # determine the port->msg buffer mappings 19310963Sdavid.hashe@amd.com def getBufferMaps(self, ident): 19410963Sdavid.hashe@amd.com msg_bufs = [] 19510963Sdavid.hashe@amd.com port_to_buf_map = {} 19610963Sdavid.hashe@amd.com in_msg_bufs = {} 19710963Sdavid.hashe@amd.com for port in self.in_ports: 19810963Sdavid.hashe@amd.com buf_name = "m_%s_ptr" % port.buffer_expr.name 19910963Sdavid.hashe@amd.com msg_bufs.append(buf_name) 20010963Sdavid.hashe@amd.com port_to_buf_map[port] = msg_bufs.index(buf_name) 20110963Sdavid.hashe@amd.com if buf_name not in in_msg_bufs: 20210963Sdavid.hashe@amd.com in_msg_bufs[buf_name] = [port] 20310963Sdavid.hashe@amd.com else: 20410963Sdavid.hashe@amd.com in_msg_bufs[buf_name].append(port) 20510963Sdavid.hashe@amd.com return port_to_buf_map, in_msg_bufs, msg_bufs 20610963Sdavid.hashe@amd.com 2079219Spower.jg@gmail.com def writeCodeFiles(self, path, includes): 2086877Ssteve.reinhardt@amd.com self.printControllerPython(path) 2096657Snate@binkert.org self.printControllerHH(path) 2109219Spower.jg@gmail.com self.printControllerCC(path, includes) 2116657Snate@binkert.org self.printCSwitch(path) 2129219Spower.jg@gmail.com self.printCWakeup(path, includes) 2136657Snate@binkert.org 2146877Ssteve.reinhardt@amd.com def printControllerPython(self, path): 2156999Snate@binkert.org code = self.symtab.codeFormatter() 2166877Ssteve.reinhardt@amd.com ident = self.ident 21710308Snilay@cs.wisc.edu 2186877Ssteve.reinhardt@amd.com py_ident = "%s_Controller" % ident 2196877Ssteve.reinhardt@amd.com c_ident = "%s_Controller" % self.ident 22010308Snilay@cs.wisc.edu 2216877Ssteve.reinhardt@amd.com code(''' 2226877Ssteve.reinhardt@amd.comfrom m5.params import * 2236877Ssteve.reinhardt@amd.comfrom m5.SimObject import SimObject 2246877Ssteve.reinhardt@amd.comfrom Controller import RubyController 2256877Ssteve.reinhardt@amd.com 2266877Ssteve.reinhardt@amd.comclass $py_ident(RubyController): 2276877Ssteve.reinhardt@amd.com type = '$py_ident' 2289338SAndreas.Sandberg@arm.com cxx_header = 'mem/protocol/${c_ident}.hh' 2296877Ssteve.reinhardt@amd.com''') 2306877Ssteve.reinhardt@amd.com code.indent() 2316877Ssteve.reinhardt@amd.com for param in self.config_parameters: 2326877Ssteve.reinhardt@amd.com dflt_str = '' 23310308Snilay@cs.wisc.edu 23410308Snilay@cs.wisc.edu if param.rvalue is not None: 23510308Snilay@cs.wisc.edu dflt_str = str(param.rvalue.inline()) + ', ' 23610308Snilay@cs.wisc.edu 23710311Snilay@cs.wisc.edu if param.type_ast.type.c_ident == "MessageBuffer": 23811021Sjthestness@gmail.com # The MessageBuffer MUST be instantiated in the protocol config 23911021Sjthestness@gmail.com code('${{param.ident}} = Param.MessageBuffer("")') 24010311Snilay@cs.wisc.edu 24110311Snilay@cs.wisc.edu elif python_class_map.has_key(param.type_ast.type.c_ident): 2426882SBrad.Beckmann@amd.com python_type = python_class_map[param.type_ast.type.c_ident] 24310308Snilay@cs.wisc.edu code('${{param.ident}} = Param.${{python_type}}(${dflt_str}"")') 24410308Snilay@cs.wisc.edu 2456882SBrad.Beckmann@amd.com else: 2466882SBrad.Beckmann@amd.com self.error("Unknown c++ to python class conversion for c++ " \ 2476882SBrad.Beckmann@amd.com "type: '%s'. Please update the python_class_map " \ 2486882SBrad.Beckmann@amd.com "in StateMachine.py", param.type_ast.type.c_ident) 24911021Sjthestness@gmail.com 25011021Sjthestness@gmail.com # Also add any MessageBuffers declared internally to the controller 25111021Sjthestness@gmail.com # Note: This includes mandatory and memory queues 25211021Sjthestness@gmail.com for var in self.objects: 25311021Sjthestness@gmail.com if var.type.c_ident == "MessageBuffer": 25411021Sjthestness@gmail.com code('${{var.ident}} = Param.MessageBuffer("")') 25511021Sjthestness@gmail.com 2566877Ssteve.reinhardt@amd.com code.dedent() 2576877Ssteve.reinhardt@amd.com code.write(path, '%s.py' % py_ident) 25810917Sbrandon.potter@amd.com 2596877Ssteve.reinhardt@amd.com 2606657Snate@binkert.org def printControllerHH(self, path): 2616657Snate@binkert.org '''Output the method declarations for the class declaration''' 2626999Snate@binkert.org code = self.symtab.codeFormatter() 2636657Snate@binkert.org ident = self.ident 2646657Snate@binkert.org c_ident = "%s_Controller" % self.ident 2656657Snate@binkert.org 2666657Snate@binkert.org code(''' 2677007Snate@binkert.org/** \\file $c_ident.hh 2686657Snate@binkert.org * 2696657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 2706657Snate@binkert.org * Created by slicc definition of Module "${{self.short}}" 2716657Snate@binkert.org */ 2726657Snate@binkert.org 2737007Snate@binkert.org#ifndef __${ident}_CONTROLLER_HH__ 2747007Snate@binkert.org#define __${ident}_CONTROLLER_HH__ 2756657Snate@binkert.org 2767002Snate@binkert.org#include <iostream> 2777002Snate@binkert.org#include <sstream> 2787002Snate@binkert.org#include <string> 2797002Snate@binkert.org 2806657Snate@binkert.org#include "mem/protocol/TransitionResult.hh" 2816657Snate@binkert.org#include "mem/protocol/Types.hh" 2828229Snate@binkert.org#include "mem/ruby/common/Consumer.hh" 2838229Snate@binkert.org#include "mem/ruby/slicc_interface/AbstractController.hh" 2848229Snate@binkert.org#include "params/$c_ident.hh" 28510972Sdavid.hashe@amd.com 2866657Snate@binkert.org''') 2876657Snate@binkert.org 2886657Snate@binkert.org seen_types = set() 2896657Snate@binkert.org for var in self.objects: 2906793SBrad.Beckmann@amd.com if var.type.ident not in seen_types and not var.type.isPrimitive: 2916657Snate@binkert.org code('#include "mem/protocol/${{var.type.c_ident}}.hh"') 29210311Snilay@cs.wisc.edu seen_types.add(var.type.ident) 2936657Snate@binkert.org 2946657Snate@binkert.org # for adding information to the protocol debug trace 2956657Snate@binkert.org code(''' 2967002Snate@binkert.orgextern std::stringstream ${ident}_transitionComment; 2976657Snate@binkert.org 2987007Snate@binkert.orgclass $c_ident : public AbstractController 2997007Snate@binkert.org{ 3009271Snilay@cs.wisc.edu public: 3016877Ssteve.reinhardt@amd.com typedef ${c_ident}Params Params; 3026877Ssteve.reinhardt@amd.com $c_ident(const Params *p); 3036657Snate@binkert.org static int getNumControllers(); 3046877Ssteve.reinhardt@amd.com void init(); 30510311Snilay@cs.wisc.edu 3066657Snate@binkert.org MessageBuffer* getMandatoryQueue() const; 30711021Sjthestness@gmail.com MessageBuffer* getMemoryQueue() const; 30811021Sjthestness@gmail.com void initNetQueues(); 3099745Snilay@cs.wisc.edu 3107002Snate@binkert.org void print(std::ostream& out) const; 3116657Snate@binkert.org void wakeup(); 31210012Snilay@cs.wisc.edu void resetStats(); 3139745Snilay@cs.wisc.edu void regStats(); 3149745Snilay@cs.wisc.edu void collateStats(); 3159745Snilay@cs.wisc.edu 3168683Snilay@cs.wisc.edu void recordCacheTrace(int cntrl, CacheRecorder* tr); 3178683Snilay@cs.wisc.edu Sequencer* getSequencer() const; 3187007Snate@binkert.org 31910524Snilay@cs.wisc.edu int functionalWriteBuffers(PacketPtr&); 3209302Snilay@cs.wisc.edu 3219745Snilay@cs.wisc.edu void countTransition(${ident}_State state, ${ident}_Event event); 3229745Snilay@cs.wisc.edu void possibleTransition(${ident}_State state, ${ident}_Event event); 32311049Snilay@cs.wisc.edu uint64 getEventCount(${ident}_Event event); 3249745Snilay@cs.wisc.edu bool isPossible(${ident}_State state, ${ident}_Event event); 32511049Snilay@cs.wisc.edu uint64 getTransitionCount(${ident}_State state, ${ident}_Event event); 3269745Snilay@cs.wisc.edu 3276657Snate@binkert.orgprivate: 3286657Snate@binkert.org''') 3296657Snate@binkert.org 3306657Snate@binkert.org code.indent() 3316657Snate@binkert.org # added by SS 3326657Snate@binkert.org for param in self.config_parameters: 3336882SBrad.Beckmann@amd.com if param.pointer: 3346882SBrad.Beckmann@amd.com code('${{param.type_ast.type}}* m_${{param.ident}}_ptr;') 3356882SBrad.Beckmann@amd.com else: 3366882SBrad.Beckmann@amd.com code('${{param.type_ast.type}} m_${{param.ident}};') 3376657Snate@binkert.org 3386657Snate@binkert.org code(''' 3397007Snate@binkert.orgTransitionResult doTransition(${ident}_Event event, 3407839Snilay@cs.wisc.edu''') 3417839Snilay@cs.wisc.edu 3427839Snilay@cs.wisc.edu if self.EntryType != None: 3437839Snilay@cs.wisc.edu code(''' 3447839Snilay@cs.wisc.edu ${{self.EntryType.c_ident}}* m_cache_entry_ptr, 3457839Snilay@cs.wisc.edu''') 3467839Snilay@cs.wisc.edu if self.TBEType != None: 3477839Snilay@cs.wisc.edu code(''' 3487839Snilay@cs.wisc.edu ${{self.TBEType.c_ident}}* m_tbe_ptr, 3497839Snilay@cs.wisc.edu''') 3507839Snilay@cs.wisc.edu 3517839Snilay@cs.wisc.edu code(''' 35211025Snilay@cs.wisc.edu Addr addr); 3537007Snate@binkert.org 3547007Snate@binkert.orgTransitionResult doTransitionWorker(${ident}_Event event, 3557007Snate@binkert.org ${ident}_State state, 3567007Snate@binkert.org ${ident}_State& next_state, 3577839Snilay@cs.wisc.edu''') 3587839Snilay@cs.wisc.edu 3597839Snilay@cs.wisc.edu if self.TBEType != None: 3607839Snilay@cs.wisc.edu code(''' 3617839Snilay@cs.wisc.edu ${{self.TBEType.c_ident}}*& m_tbe_ptr, 3627839Snilay@cs.wisc.edu''') 3637839Snilay@cs.wisc.edu if self.EntryType != None: 3647839Snilay@cs.wisc.edu code(''' 3657839Snilay@cs.wisc.edu ${{self.EntryType.c_ident}}*& m_cache_entry_ptr, 3667839Snilay@cs.wisc.edu''') 3677839Snilay@cs.wisc.edu 3687839Snilay@cs.wisc.edu code(''' 36911025Snilay@cs.wisc.edu Addr addr); 3707007Snate@binkert.org 3719745Snilay@cs.wisc.eduint m_counters[${ident}_State_NUM][${ident}_Event_NUM]; 3729745Snilay@cs.wisc.eduint m_event_counters[${ident}_Event_NUM]; 3739745Snilay@cs.wisc.edubool m_possible[${ident}_State_NUM][${ident}_Event_NUM]; 3749745Snilay@cs.wisc.edu 3759745Snilay@cs.wisc.edustatic std::vector<Stats::Vector *> eventVec; 3769745Snilay@cs.wisc.edustatic std::vector<std::vector<Stats::Vector *> > transVec; 3776657Snate@binkert.orgstatic int m_num_controllers; 3787007Snate@binkert.org 3796657Snate@binkert.org// Internal functions 3806657Snate@binkert.org''') 3816657Snate@binkert.org 3826657Snate@binkert.org for func in self.functions: 3836657Snate@binkert.org proto = func.prototype 3846657Snate@binkert.org if proto: 3856657Snate@binkert.org code('$proto') 3866657Snate@binkert.org 3877839Snilay@cs.wisc.edu if self.EntryType != None: 3887839Snilay@cs.wisc.edu code(''' 3897839Snilay@cs.wisc.edu 3907839Snilay@cs.wisc.edu// Set and Reset for cache_entry variable 3917839Snilay@cs.wisc.eduvoid set_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr, AbstractCacheEntry* m_new_cache_entry); 3927839Snilay@cs.wisc.eduvoid unset_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr); 3937839Snilay@cs.wisc.edu''') 3947839Snilay@cs.wisc.edu 3957839Snilay@cs.wisc.edu if self.TBEType != None: 3967839Snilay@cs.wisc.edu code(''' 3977839Snilay@cs.wisc.edu 3987839Snilay@cs.wisc.edu// Set and Reset for tbe variable 3997839Snilay@cs.wisc.eduvoid set_tbe(${{self.TBEType.c_ident}}*& m_tbe_ptr, ${ident}_TBE* m_new_tbe); 4007839Snilay@cs.wisc.eduvoid unset_tbe(${{self.TBEType.c_ident}}*& m_tbe_ptr); 4017839Snilay@cs.wisc.edu''') 4027839Snilay@cs.wisc.edu 40310121Snilay@cs.wisc.edu # Prototype the actions that the controller can take 4046657Snate@binkert.org code(''' 4056657Snate@binkert.org 4066657Snate@binkert.org// Actions 4076657Snate@binkert.org''') 4087839Snilay@cs.wisc.edu if self.TBEType != None and self.EntryType != None: 4097839Snilay@cs.wisc.edu for action in self.actions.itervalues(): 4107839Snilay@cs.wisc.edu code('/** \\brief ${{action.desc}} */') 41110121Snilay@cs.wisc.edu code('void ${{action.ident}}(${{self.TBEType.c_ident}}*& ' 41210121Snilay@cs.wisc.edu 'm_tbe_ptr, ${{self.EntryType.c_ident}}*& ' 41311025Snilay@cs.wisc.edu 'm_cache_entry_ptr, Addr addr);') 4147839Snilay@cs.wisc.edu elif self.TBEType != None: 4157839Snilay@cs.wisc.edu for action in self.actions.itervalues(): 4167839Snilay@cs.wisc.edu code('/** \\brief ${{action.desc}} */') 41710121Snilay@cs.wisc.edu code('void ${{action.ident}}(${{self.TBEType.c_ident}}*& ' 41811025Snilay@cs.wisc.edu 'm_tbe_ptr, Addr addr);') 4197839Snilay@cs.wisc.edu elif self.EntryType != None: 4207839Snilay@cs.wisc.edu for action in self.actions.itervalues(): 4217839Snilay@cs.wisc.edu code('/** \\brief ${{action.desc}} */') 42210121Snilay@cs.wisc.edu code('void ${{action.ident}}(${{self.EntryType.c_ident}}*& ' 42311025Snilay@cs.wisc.edu 'm_cache_entry_ptr, Addr addr);') 4247839Snilay@cs.wisc.edu else: 4257839Snilay@cs.wisc.edu for action in self.actions.itervalues(): 4267839Snilay@cs.wisc.edu code('/** \\brief ${{action.desc}} */') 42711025Snilay@cs.wisc.edu code('void ${{action.ident}}(Addr addr);') 4286657Snate@binkert.org 4296657Snate@binkert.org # the controller internal variables 4306657Snate@binkert.org code(''' 4316657Snate@binkert.org 4327007Snate@binkert.org// Objects 4336657Snate@binkert.org''') 4346657Snate@binkert.org for var in self.objects: 4359273Snilay@cs.wisc.edu th = var.get("template", "") 43610305Snilay@cs.wisc.edu code('${{var.type.c_ident}}$th* m_${{var.ident}}_ptr;') 4376657Snate@binkert.org 4386657Snate@binkert.org code.dedent() 4396657Snate@binkert.org code('};') 4407007Snate@binkert.org code('#endif // __${ident}_CONTROLLER_H__') 4416657Snate@binkert.org code.write(path, '%s.hh' % c_ident) 4426657Snate@binkert.org 4439219Spower.jg@gmail.com def printControllerCC(self, path, includes): 4446657Snate@binkert.org '''Output the actions for performing the actions''' 4456657Snate@binkert.org 4466999Snate@binkert.org code = self.symtab.codeFormatter() 4476657Snate@binkert.org ident = self.ident 4486657Snate@binkert.org c_ident = "%s_Controller" % self.ident 4496657Snate@binkert.org 4506657Snate@binkert.org code(''' 4517007Snate@binkert.org/** \\file $c_ident.cc 4526657Snate@binkert.org * 4536657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 4546657Snate@binkert.org * Created by slicc definition of Module "${{self.short}}" 4556657Snate@binkert.org */ 4566657Snate@binkert.org 4578946Sandreas.hansson@arm.com#include <sys/types.h> 4588946Sandreas.hansson@arm.com#include <unistd.h> 4598946Sandreas.hansson@arm.com 4607832Snate@binkert.org#include <cassert> 4617002Snate@binkert.org#include <sstream> 4627002Snate@binkert.org#include <string> 46310972Sdavid.hashe@amd.com#include <typeinfo> 4647002Snate@binkert.org 4658641Snate@binkert.org#include "base/compiler.hh" 4667056Snate@binkert.org#include "base/cprintf.hh" 46710972Sdavid.hashe@amd.com 46810972Sdavid.hashe@amd.com''') 46910972Sdavid.hashe@amd.com for f in self.debug_flags: 47010972Sdavid.hashe@amd.com code('#include "debug/${{f}}.hh"') 47110972Sdavid.hashe@amd.com code(''' 4726657Snate@binkert.org#include "mem/protocol/${ident}_Controller.hh" 4738229Snate@binkert.org#include "mem/protocol/${ident}_Event.hh" 4746657Snate@binkert.org#include "mem/protocol/${ident}_State.hh" 4756657Snate@binkert.org#include "mem/protocol/Types.hh" 4766657Snate@binkert.org#include "mem/ruby/system/System.hh" 47710972Sdavid.hashe@amd.com 4789219Spower.jg@gmail.com''') 4799219Spower.jg@gmail.com for include_path in includes: 4809219Spower.jg@gmail.com code('#include "${{include_path}}"') 4819219Spower.jg@gmail.com 4829219Spower.jg@gmail.com code(''' 4837002Snate@binkert.org 4847002Snate@binkert.orgusing namespace std; 4856657Snate@binkert.org''') 4866657Snate@binkert.org 4876657Snate@binkert.org # include object classes 4886657Snate@binkert.org seen_types = set() 4896657Snate@binkert.org for var in self.objects: 4906793SBrad.Beckmann@amd.com if var.type.ident not in seen_types and not var.type.isPrimitive: 4916657Snate@binkert.org code('#include "mem/protocol/${{var.type.c_ident}}.hh"') 4926657Snate@binkert.org seen_types.add(var.type.ident) 4936657Snate@binkert.org 49410121Snilay@cs.wisc.edu num_in_ports = len(self.in_ports) 49510121Snilay@cs.wisc.edu 4966657Snate@binkert.org code(''' 4976877Ssteve.reinhardt@amd.com$c_ident * 4986877Ssteve.reinhardt@amd.com${c_ident}Params::create() 4996877Ssteve.reinhardt@amd.com{ 5006877Ssteve.reinhardt@amd.com return new $c_ident(this); 5016877Ssteve.reinhardt@amd.com} 5026877Ssteve.reinhardt@amd.com 5036657Snate@binkert.orgint $c_ident::m_num_controllers = 0; 5049745Snilay@cs.wisc.edustd::vector<Stats::Vector *> $c_ident::eventVec; 5059745Snilay@cs.wisc.edustd::vector<std::vector<Stats::Vector *> > $c_ident::transVec; 5066657Snate@binkert.org 5077007Snate@binkert.org// for adding information to the protocol debug trace 5086657Snate@binkert.orgstringstream ${ident}_transitionComment; 5099801Snilay@cs.wisc.edu 5109801Snilay@cs.wisc.edu#ifndef NDEBUG 5116657Snate@binkert.org#define APPEND_TRANSITION_COMMENT(str) (${ident}_transitionComment << str) 5129801Snilay@cs.wisc.edu#else 5139801Snilay@cs.wisc.edu#define APPEND_TRANSITION_COMMENT(str) do {} while (0) 5149801Snilay@cs.wisc.edu#endif 5157007Snate@binkert.org 5166657Snate@binkert.org/** \\brief constructor */ 5176877Ssteve.reinhardt@amd.com$c_ident::$c_ident(const Params *p) 5186877Ssteve.reinhardt@amd.com : AbstractController(p) 5196657Snate@binkert.org{ 52010078Snilay@cs.wisc.edu m_machineID.type = MachineType_${ident}; 52110078Snilay@cs.wisc.edu m_machineID.num = m_version; 52210121Snilay@cs.wisc.edu m_num_controllers++; 52310121Snilay@cs.wisc.edu 52410121Snilay@cs.wisc.edu m_in_ports = $num_in_ports; 5256657Snate@binkert.org''') 5266657Snate@binkert.org code.indent() 5276882SBrad.Beckmann@amd.com 5286882SBrad.Beckmann@amd.com # 5296882SBrad.Beckmann@amd.com # After initializing the universal machine parameters, initialize the 53010121Snilay@cs.wisc.edu # this machines config parameters. Also if these configuration params 53110121Snilay@cs.wisc.edu # include a sequencer, connect the it to the controller. 5326882SBrad.Beckmann@amd.com # 5336877Ssteve.reinhardt@amd.com for param in self.config_parameters: 5346882SBrad.Beckmann@amd.com if param.pointer: 53510308Snilay@cs.wisc.edu code('m_${{param.ident}}_ptr = p->${{param.ident}};') 5366882SBrad.Beckmann@amd.com else: 53710308Snilay@cs.wisc.edu code('m_${{param.ident}} = p->${{param.ident}};') 53810311Snilay@cs.wisc.edu 53910308Snilay@cs.wisc.edu if re.compile("sequencer").search(param.ident): 54010308Snilay@cs.wisc.edu code('m_${{param.ident}}_ptr->setController(this);') 54110917Sbrandon.potter@amd.com 5426657Snate@binkert.org for var in self.objects: 54311021Sjthestness@gmail.com # Some MessageBuffers (e.g. mandatory and memory queues) are 54411021Sjthestness@gmail.com # instantiated internally to StateMachines but exposed to 54511021Sjthestness@gmail.com # components outside SLICC, so make sure to set up this 54611021Sjthestness@gmail.com # controller as their receivers 54711021Sjthestness@gmail.com if var.type.c_ident == "MessageBuffer": 5489508Snilay@cs.wisc.edu code(''' 54911021Sjthestness@gmail.comm_${{var.ident}}_ptr = p->${{var.ident}}; 55010305Snilay@cs.wisc.edum_${{var.ident}}_ptr->setReceiver(this); 5519508Snilay@cs.wisc.edu''') 5526657Snate@binkert.org 5539595Snilay@cs.wisc.edu code(''' 5549745Snilay@cs.wisc.edu 5559745Snilay@cs.wisc.edufor (int state = 0; state < ${ident}_State_NUM; state++) { 5569745Snilay@cs.wisc.edu for (int event = 0; event < ${ident}_Event_NUM; event++) { 5579745Snilay@cs.wisc.edu m_possible[state][event] = false; 5589745Snilay@cs.wisc.edu m_counters[state][event] = 0; 5599745Snilay@cs.wisc.edu } 5609745Snilay@cs.wisc.edu} 5619745Snilay@cs.wisc.edufor (int event = 0; event < ${ident}_Event_NUM; event++) { 5629745Snilay@cs.wisc.edu m_event_counters[event] = 0; 5639745Snilay@cs.wisc.edu} 5649595Snilay@cs.wisc.edu''') 5656657Snate@binkert.org code.dedent() 5666657Snate@binkert.org code(''' 5676657Snate@binkert.org} 5686657Snate@binkert.org 5697007Snate@binkert.orgvoid 57011021Sjthestness@gmail.com$c_ident::initNetQueues() 57110311Snilay@cs.wisc.edu{ 57210311Snilay@cs.wisc.edu MachineType machine_type = string_to_MachineType("${{self.ident}}"); 57310311Snilay@cs.wisc.edu int base M5_VAR_USED = MachineType_base_number(machine_type); 57410311Snilay@cs.wisc.edu 57510311Snilay@cs.wisc.edu''') 57610311Snilay@cs.wisc.edu code.indent() 57710311Snilay@cs.wisc.edu 57810311Snilay@cs.wisc.edu # set for maintaining the vnet, direction pairs already seen for this 57910311Snilay@cs.wisc.edu # machine. This map helps in implementing the check for avoiding 58010311Snilay@cs.wisc.edu # multiple message buffers being mapped to the same vnet. 58110311Snilay@cs.wisc.edu vnet_dir_set = set() 58210311Snilay@cs.wisc.edu 58310311Snilay@cs.wisc.edu for var in self.config_parameters: 58410311Snilay@cs.wisc.edu if "network" in var: 58510311Snilay@cs.wisc.edu vtype = var.type_ast.type 58610311Snilay@cs.wisc.edu vid = "m_%s_ptr" % var.ident 58710311Snilay@cs.wisc.edu 58811021Sjthestness@gmail.com code('assert($vid != NULL);') 58911021Sjthestness@gmail.com 59010311Snilay@cs.wisc.edu # Network port object 59110311Snilay@cs.wisc.edu network = var["network"] 59210311Snilay@cs.wisc.edu 59310311Snilay@cs.wisc.edu if "virtual_network" in var: 59410311Snilay@cs.wisc.edu vnet = var["virtual_network"] 59510311Snilay@cs.wisc.edu vnet_type = var["vnet_type"] 59610311Snilay@cs.wisc.edu 59710311Snilay@cs.wisc.edu assert (vnet, network) not in vnet_dir_set 59810311Snilay@cs.wisc.edu vnet_dir_set.add((vnet,network)) 59910311Snilay@cs.wisc.edu 60010311Snilay@cs.wisc.edu code(''' 60111021Sjthestness@gmail.comm_net_ptr->set${network}NetQueue(m_version + base, $vid->getOrdered(), $vnet, 60211021Sjthestness@gmail.com "$vnet_type", $vid); 60310311Snilay@cs.wisc.edu''') 60410311Snilay@cs.wisc.edu # Set the end 60510311Snilay@cs.wisc.edu if network == "To": 60610311Snilay@cs.wisc.edu code('$vid->setSender(this);') 60710311Snilay@cs.wisc.edu else: 60810311Snilay@cs.wisc.edu code('$vid->setReceiver(this);') 60910311Snilay@cs.wisc.edu 61010311Snilay@cs.wisc.edu # Set Priority 61110311Snilay@cs.wisc.edu if "rank" in var: 61210311Snilay@cs.wisc.edu code('$vid->setPriority(${{var["rank"]}})') 61310311Snilay@cs.wisc.edu 61410311Snilay@cs.wisc.edu code.dedent() 61510311Snilay@cs.wisc.edu code(''' 61610311Snilay@cs.wisc.edu} 61710311Snilay@cs.wisc.edu 61810311Snilay@cs.wisc.eduvoid 6197007Snate@binkert.org$c_ident::init() 6206657Snate@binkert.org{ 6217007Snate@binkert.org // initialize objects 62211021Sjthestness@gmail.com initNetQueues(); 6236657Snate@binkert.org''') 6246657Snate@binkert.org 6256657Snate@binkert.org code.indent() 62610311Snilay@cs.wisc.edu 6276657Snate@binkert.org for var in self.objects: 6286657Snate@binkert.org vtype = var.type 62910305Snilay@cs.wisc.edu vid = "m_%s_ptr" % var.ident 6306657Snate@binkert.org if "network" not in var: 6316657Snate@binkert.org # Not a network port object 6326657Snate@binkert.org if "primitive" in vtype: 6336657Snate@binkert.org code('$vid = new ${{vtype.c_ident}};') 6346657Snate@binkert.org if "default" in var: 6356657Snate@binkert.org code('(*$vid) = ${{var["default"]}};') 6366657Snate@binkert.org else: 6376657Snate@binkert.org # Normal Object 63811021Sjthestness@gmail.com if var.type.c_ident != "MessageBuffer": 6399273Snilay@cs.wisc.edu th = var.get("template", "") 6406657Snate@binkert.org expr = "%s = new %s%s" % (vid, vtype.c_ident, th) 6416657Snate@binkert.org args = "" 6426657Snate@binkert.org if "non_obj" not in vtype and not vtype.isEnumeration: 6439364Snilay@cs.wisc.edu args = var.get("constructor", "") 6447007Snate@binkert.org code('$expr($args);') 6456657Snate@binkert.org 6466657Snate@binkert.org code('assert($vid != NULL);') 6476657Snate@binkert.org 6486657Snate@binkert.org if "default" in var: 6497007Snate@binkert.org code('*$vid = ${{var["default"]}}; // Object default') 6506657Snate@binkert.org elif "default" in vtype: 6517007Snate@binkert.org comment = "Type %s default" % vtype.ident 6527007Snate@binkert.org code('*$vid = ${{vtype["default"]}}; // $comment') 6536657Snate@binkert.org 6546657Snate@binkert.org # Set Priority 6559508Snilay@cs.wisc.edu if vtype.isBuffer and "rank" in var: 6566657Snate@binkert.org code('$vid->setPriority(${{var["rank"]}});') 6577566SBrad.Beckmann@amd.com 6589508Snilay@cs.wisc.edu # Set sender and receiver for trigger queue 6599508Snilay@cs.wisc.edu if var.ident.find("triggerQueue") >= 0: 6609508Snilay@cs.wisc.edu code('$vid->setSender(this);') 6619508Snilay@cs.wisc.edu code('$vid->setReceiver(this);') 6629508Snilay@cs.wisc.edu elif vtype.c_ident == "TimerTable": 6639508Snilay@cs.wisc.edu code('$vid->setClockObj(this);') 6649604Snilay@cs.wisc.edu elif var.ident.find("optionalQueue") >= 0: 6659604Snilay@cs.wisc.edu code('$vid->setSender(this);') 6669604Snilay@cs.wisc.edu code('$vid->setReceiver(this);') 6679508Snilay@cs.wisc.edu 6689366Snilay@cs.wisc.edu # Set the prefetchers 6699366Snilay@cs.wisc.edu code() 6709366Snilay@cs.wisc.edu for prefetcher in self.prefetchers: 6719366Snilay@cs.wisc.edu code('${{prefetcher.code}}.setController(this);') 6727566SBrad.Beckmann@amd.com 6737672Snate@binkert.org code() 6746657Snate@binkert.org for port in self.in_ports: 6759465Snilay@cs.wisc.edu # Set the queue consumers 6766657Snate@binkert.org code('${{port.code}}.setConsumer(this);') 6776657Snate@binkert.org 6786657Snate@binkert.org # Initialize the transition profiling 6797672Snate@binkert.org code() 6806657Snate@binkert.org for trans in self.transitions: 6816657Snate@binkert.org # Figure out if we stall 6826657Snate@binkert.org stall = False 6836657Snate@binkert.org for action in trans.actions: 6846657Snate@binkert.org if action.ident == "z_stall": 6856657Snate@binkert.org stall = True 6866657Snate@binkert.org 6876657Snate@binkert.org # Only possible if it is not a 'z' case 6886657Snate@binkert.org if not stall: 6896657Snate@binkert.org state = "%s_State_%s" % (self.ident, trans.state.ident) 6906657Snate@binkert.org event = "%s_Event_%s" % (self.ident, trans.event.ident) 6919745Snilay@cs.wisc.edu code('possibleTransition($state, $event);') 6926657Snate@binkert.org 6936657Snate@binkert.org code.dedent() 6949496Snilay@cs.wisc.edu code(''' 6959496Snilay@cs.wisc.edu AbstractController::init(); 69610012Snilay@cs.wisc.edu resetStats(); 6979496Snilay@cs.wisc.edu} 6989496Snilay@cs.wisc.edu''') 6996657Snate@binkert.org 70010121Snilay@cs.wisc.edu mq_ident = "NULL" 7016657Snate@binkert.org for port in self.in_ports: 7026657Snate@binkert.org if port.code.find("mandatoryQueue_ptr") >= 0: 70310305Snilay@cs.wisc.edu mq_ident = "m_mandatoryQueue_ptr" 7046657Snate@binkert.org 70511021Sjthestness@gmail.com memq_ident = "NULL" 70611021Sjthestness@gmail.com for port in self.in_ports: 70711021Sjthestness@gmail.com if port.code.find("responseFromMemory_ptr") >= 0: 70811021Sjthestness@gmail.com memq_ident = "m_responseFromMemory_ptr" 70911021Sjthestness@gmail.com 7108683Snilay@cs.wisc.edu seq_ident = "NULL" 7118683Snilay@cs.wisc.edu for param in self.config_parameters: 71210308Snilay@cs.wisc.edu if param.ident == "sequencer": 7138683Snilay@cs.wisc.edu assert(param.pointer) 71410308Snilay@cs.wisc.edu seq_ident = "m_%s_ptr" % param.ident 7158683Snilay@cs.wisc.edu 7166657Snate@binkert.org code(''' 7179745Snilay@cs.wisc.edu 7189745Snilay@cs.wisc.eduvoid 7199745Snilay@cs.wisc.edu$c_ident::regStats() 7209745Snilay@cs.wisc.edu{ 72110012Snilay@cs.wisc.edu AbstractController::regStats(); 72210012Snilay@cs.wisc.edu 7239745Snilay@cs.wisc.edu if (m_version == 0) { 7249745Snilay@cs.wisc.edu for (${ident}_Event event = ${ident}_Event_FIRST; 7259745Snilay@cs.wisc.edu event < ${ident}_Event_NUM; ++event) { 7269745Snilay@cs.wisc.edu Stats::Vector *t = new Stats::Vector(); 7279745Snilay@cs.wisc.edu t->init(m_num_controllers); 72810919Sbrandon.potter@amd.com t->name(params()->ruby_system->name() + ".${c_ident}." + 72910012Snilay@cs.wisc.edu ${ident}_Event_to_string(event)); 7309745Snilay@cs.wisc.edu t->flags(Stats::pdf | Stats::total | Stats::oneline | 7319745Snilay@cs.wisc.edu Stats::nozero); 7329745Snilay@cs.wisc.edu 7339745Snilay@cs.wisc.edu eventVec.push_back(t); 7349745Snilay@cs.wisc.edu } 7359745Snilay@cs.wisc.edu 7369745Snilay@cs.wisc.edu for (${ident}_State state = ${ident}_State_FIRST; 7379745Snilay@cs.wisc.edu state < ${ident}_State_NUM; ++state) { 7389745Snilay@cs.wisc.edu 7399745Snilay@cs.wisc.edu transVec.push_back(std::vector<Stats::Vector *>()); 7409745Snilay@cs.wisc.edu 7419745Snilay@cs.wisc.edu for (${ident}_Event event = ${ident}_Event_FIRST; 7429745Snilay@cs.wisc.edu event < ${ident}_Event_NUM; ++event) { 7439745Snilay@cs.wisc.edu 7449745Snilay@cs.wisc.edu Stats::Vector *t = new Stats::Vector(); 7459745Snilay@cs.wisc.edu t->init(m_num_controllers); 74610919Sbrandon.potter@amd.com t->name(params()->ruby_system->name() + ".${c_ident}." + 74710012Snilay@cs.wisc.edu ${ident}_State_to_string(state) + 7489745Snilay@cs.wisc.edu "." + ${ident}_Event_to_string(event)); 7499745Snilay@cs.wisc.edu 7509745Snilay@cs.wisc.edu t->flags(Stats::pdf | Stats::total | Stats::oneline | 7519745Snilay@cs.wisc.edu Stats::nozero); 7529745Snilay@cs.wisc.edu transVec[state].push_back(t); 7539745Snilay@cs.wisc.edu } 7549745Snilay@cs.wisc.edu } 7559745Snilay@cs.wisc.edu } 7569745Snilay@cs.wisc.edu} 7579745Snilay@cs.wisc.edu 7589745Snilay@cs.wisc.eduvoid 7599745Snilay@cs.wisc.edu$c_ident::collateStats() 7609745Snilay@cs.wisc.edu{ 7619745Snilay@cs.wisc.edu for (${ident}_Event event = ${ident}_Event_FIRST; 7629745Snilay@cs.wisc.edu event < ${ident}_Event_NUM; ++event) { 7639745Snilay@cs.wisc.edu for (unsigned int i = 0; i < m_num_controllers; ++i) { 76410920Sbrandon.potter@amd.com RubySystem *rs = params()->ruby_system; 7659745Snilay@cs.wisc.edu std::map<uint32_t, AbstractController *>::iterator it = 76610920Sbrandon.potter@amd.com rs->m_abstract_controls[MachineType_${ident}].find(i); 76710920Sbrandon.potter@amd.com assert(it != rs->m_abstract_controls[MachineType_${ident}].end()); 7689745Snilay@cs.wisc.edu (*eventVec[event])[i] = 7699745Snilay@cs.wisc.edu (($c_ident *)(*it).second)->getEventCount(event); 7709745Snilay@cs.wisc.edu } 7719745Snilay@cs.wisc.edu } 7729745Snilay@cs.wisc.edu 7739745Snilay@cs.wisc.edu for (${ident}_State state = ${ident}_State_FIRST; 7749745Snilay@cs.wisc.edu state < ${ident}_State_NUM; ++state) { 7759745Snilay@cs.wisc.edu 7769745Snilay@cs.wisc.edu for (${ident}_Event event = ${ident}_Event_FIRST; 7779745Snilay@cs.wisc.edu event < ${ident}_Event_NUM; ++event) { 7789745Snilay@cs.wisc.edu 7799745Snilay@cs.wisc.edu for (unsigned int i = 0; i < m_num_controllers; ++i) { 78010920Sbrandon.potter@amd.com RubySystem *rs = params()->ruby_system; 7819745Snilay@cs.wisc.edu std::map<uint32_t, AbstractController *>::iterator it = 78210920Sbrandon.potter@amd.com rs->m_abstract_controls[MachineType_${ident}].find(i); 78310920Sbrandon.potter@amd.com assert(it != rs->m_abstract_controls[MachineType_${ident}].end()); 7849745Snilay@cs.wisc.edu (*transVec[state][event])[i] = 7859745Snilay@cs.wisc.edu (($c_ident *)(*it).second)->getTransitionCount(state, event); 7869745Snilay@cs.wisc.edu } 7879745Snilay@cs.wisc.edu } 7889745Snilay@cs.wisc.edu } 7899745Snilay@cs.wisc.edu} 7909745Snilay@cs.wisc.edu 7919745Snilay@cs.wisc.eduvoid 7929745Snilay@cs.wisc.edu$c_ident::countTransition(${ident}_State state, ${ident}_Event event) 7939745Snilay@cs.wisc.edu{ 7949745Snilay@cs.wisc.edu assert(m_possible[state][event]); 7959745Snilay@cs.wisc.edu m_counters[state][event]++; 7969745Snilay@cs.wisc.edu m_event_counters[event]++; 7979745Snilay@cs.wisc.edu} 7989745Snilay@cs.wisc.eduvoid 7999745Snilay@cs.wisc.edu$c_ident::possibleTransition(${ident}_State state, 8009745Snilay@cs.wisc.edu ${ident}_Event event) 8019745Snilay@cs.wisc.edu{ 8029745Snilay@cs.wisc.edu m_possible[state][event] = true; 8039745Snilay@cs.wisc.edu} 8049745Snilay@cs.wisc.edu 80511049Snilay@cs.wisc.eduuint64 8069745Snilay@cs.wisc.edu$c_ident::getEventCount(${ident}_Event event) 8079745Snilay@cs.wisc.edu{ 8089745Snilay@cs.wisc.edu return m_event_counters[event]; 8099745Snilay@cs.wisc.edu} 8109745Snilay@cs.wisc.edu 8119745Snilay@cs.wisc.edubool 8129745Snilay@cs.wisc.edu$c_ident::isPossible(${ident}_State state, ${ident}_Event event) 8139745Snilay@cs.wisc.edu{ 8149745Snilay@cs.wisc.edu return m_possible[state][event]; 8159745Snilay@cs.wisc.edu} 8169745Snilay@cs.wisc.edu 81711049Snilay@cs.wisc.eduuint64 8189745Snilay@cs.wisc.edu$c_ident::getTransitionCount(${ident}_State state, 8199745Snilay@cs.wisc.edu ${ident}_Event event) 8209745Snilay@cs.wisc.edu{ 8219745Snilay@cs.wisc.edu return m_counters[state][event]; 8229745Snilay@cs.wisc.edu} 8239745Snilay@cs.wisc.edu 8247007Snate@binkert.orgint 8257007Snate@binkert.org$c_ident::getNumControllers() 8267007Snate@binkert.org{ 8276657Snate@binkert.org return m_num_controllers; 8286657Snate@binkert.org} 8296657Snate@binkert.org 8307007Snate@binkert.orgMessageBuffer* 8317007Snate@binkert.org$c_ident::getMandatoryQueue() const 8327007Snate@binkert.org{ 8336657Snate@binkert.org return $mq_ident; 8346657Snate@binkert.org} 8356657Snate@binkert.org 83611021Sjthestness@gmail.comMessageBuffer* 83711021Sjthestness@gmail.com$c_ident::getMemoryQueue() const 83811021Sjthestness@gmail.com{ 83911021Sjthestness@gmail.com return $memq_ident; 84011021Sjthestness@gmail.com} 84111021Sjthestness@gmail.com 8428683Snilay@cs.wisc.eduSequencer* 8438683Snilay@cs.wisc.edu$c_ident::getSequencer() const 8448683Snilay@cs.wisc.edu{ 8458683Snilay@cs.wisc.edu return $seq_ident; 8468683Snilay@cs.wisc.edu} 8478683Snilay@cs.wisc.edu 8487007Snate@binkert.orgvoid 8497007Snate@binkert.org$c_ident::print(ostream& out) const 8507007Snate@binkert.org{ 8517007Snate@binkert.org out << "[$c_ident " << m_version << "]"; 8527007Snate@binkert.org} 8536657Snate@binkert.org 85410012Snilay@cs.wisc.eduvoid $c_ident::resetStats() 8559745Snilay@cs.wisc.edu{ 8569745Snilay@cs.wisc.edu for (int state = 0; state < ${ident}_State_NUM; state++) { 8579745Snilay@cs.wisc.edu for (int event = 0; event < ${ident}_Event_NUM; event++) { 8589745Snilay@cs.wisc.edu m_counters[state][event] = 0; 8599745Snilay@cs.wisc.edu } 8609745Snilay@cs.wisc.edu } 8616902SBrad.Beckmann@amd.com 8629745Snilay@cs.wisc.edu for (int event = 0; event < ${ident}_Event_NUM; event++) { 8639745Snilay@cs.wisc.edu m_event_counters[event] = 0; 8649745Snilay@cs.wisc.edu } 8659745Snilay@cs.wisc.edu 86610012Snilay@cs.wisc.edu AbstractController::resetStats(); 8676902SBrad.Beckmann@amd.com} 8687839Snilay@cs.wisc.edu''') 8697839Snilay@cs.wisc.edu 8707839Snilay@cs.wisc.edu if self.EntryType != None: 8717839Snilay@cs.wisc.edu code(''' 8727839Snilay@cs.wisc.edu 8737839Snilay@cs.wisc.edu// Set and Reset for cache_entry variable 8747839Snilay@cs.wisc.eduvoid 8757839Snilay@cs.wisc.edu$c_ident::set_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr, AbstractCacheEntry* m_new_cache_entry) 8767839Snilay@cs.wisc.edu{ 8777839Snilay@cs.wisc.edu m_cache_entry_ptr = (${{self.EntryType.c_ident}}*)m_new_cache_entry; 8787839Snilay@cs.wisc.edu} 8797839Snilay@cs.wisc.edu 8807839Snilay@cs.wisc.eduvoid 8817839Snilay@cs.wisc.edu$c_ident::unset_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr) 8827839Snilay@cs.wisc.edu{ 8837839Snilay@cs.wisc.edu m_cache_entry_ptr = 0; 8847839Snilay@cs.wisc.edu} 8857839Snilay@cs.wisc.edu''') 8867839Snilay@cs.wisc.edu 8877839Snilay@cs.wisc.edu if self.TBEType != None: 8887839Snilay@cs.wisc.edu code(''' 8897839Snilay@cs.wisc.edu 8907839Snilay@cs.wisc.edu// Set and Reset for tbe variable 8917839Snilay@cs.wisc.eduvoid 8927839Snilay@cs.wisc.edu$c_ident::set_tbe(${{self.TBEType.c_ident}}*& m_tbe_ptr, ${{self.TBEType.c_ident}}* m_new_tbe) 8937839Snilay@cs.wisc.edu{ 8947839Snilay@cs.wisc.edu m_tbe_ptr = m_new_tbe; 8957839Snilay@cs.wisc.edu} 8967839Snilay@cs.wisc.edu 8977839Snilay@cs.wisc.eduvoid 8987839Snilay@cs.wisc.edu$c_ident::unset_tbe(${{self.TBEType.c_ident}}*& m_tbe_ptr) 8997839Snilay@cs.wisc.edu{ 9007839Snilay@cs.wisc.edu m_tbe_ptr = NULL; 9017839Snilay@cs.wisc.edu} 9027839Snilay@cs.wisc.edu''') 9037839Snilay@cs.wisc.edu 9047839Snilay@cs.wisc.edu code(''' 9056902SBrad.Beckmann@amd.com 9068683Snilay@cs.wisc.eduvoid 9078683Snilay@cs.wisc.edu$c_ident::recordCacheTrace(int cntrl, CacheRecorder* tr) 9088683Snilay@cs.wisc.edu{ 9098683Snilay@cs.wisc.edu''') 9108683Snilay@cs.wisc.edu # 9118683Snilay@cs.wisc.edu # Record cache contents for all associated caches. 9128683Snilay@cs.wisc.edu # 9138683Snilay@cs.wisc.edu code.indent() 9148683Snilay@cs.wisc.edu for param in self.config_parameters: 9158683Snilay@cs.wisc.edu if param.type_ast.type.ident == "CacheMemory": 9168683Snilay@cs.wisc.edu assert(param.pointer) 9178683Snilay@cs.wisc.edu code('m_${{param.ident}}_ptr->recordCacheContents(cntrl, tr);') 9188683Snilay@cs.wisc.edu 9198683Snilay@cs.wisc.edu code.dedent() 9208683Snilay@cs.wisc.edu code(''' 9218683Snilay@cs.wisc.edu} 9228683Snilay@cs.wisc.edu 9236657Snate@binkert.org// Actions 9246657Snate@binkert.org''') 9257839Snilay@cs.wisc.edu if self.TBEType != None and self.EntryType != None: 9267839Snilay@cs.wisc.edu for action in self.actions.itervalues(): 9277839Snilay@cs.wisc.edu if "c_code" not in action: 9287839Snilay@cs.wisc.edu continue 9296657Snate@binkert.org 9307839Snilay@cs.wisc.edu code(''' 9317839Snilay@cs.wisc.edu/** \\brief ${{action.desc}} */ 9327839Snilay@cs.wisc.eduvoid 93311025Snilay@cs.wisc.edu$c_ident::${{action.ident}}(${{self.TBEType.c_ident}}*& m_tbe_ptr, ${{self.EntryType.c_ident}}*& m_cache_entry_ptr, Addr addr) 9347839Snilay@cs.wisc.edu{ 9358055Sksewell@umich.edu DPRINTF(RubyGenerated, "executing ${{action.ident}}\\n"); 93610963Sdavid.hashe@amd.com try { 93710963Sdavid.hashe@amd.com ${{action["c_code"]}} 93810963Sdavid.hashe@amd.com } catch (const RejectException & e) { 93910963Sdavid.hashe@amd.com fatal("Error in action ${{ident}}:${{action.ident}}: " 94010963Sdavid.hashe@amd.com "executed a peek statement with the wrong message " 94110963Sdavid.hashe@amd.com "type specified. "); 94210963Sdavid.hashe@amd.com } 9437839Snilay@cs.wisc.edu} 9446657Snate@binkert.org 9457839Snilay@cs.wisc.edu''') 9467839Snilay@cs.wisc.edu elif self.TBEType != None: 9477839Snilay@cs.wisc.edu for action in self.actions.itervalues(): 9487839Snilay@cs.wisc.edu if "c_code" not in action: 9497839Snilay@cs.wisc.edu continue 9507839Snilay@cs.wisc.edu 9517839Snilay@cs.wisc.edu code(''' 9527839Snilay@cs.wisc.edu/** \\brief ${{action.desc}} */ 9537839Snilay@cs.wisc.eduvoid 95411025Snilay@cs.wisc.edu$c_ident::${{action.ident}}(${{self.TBEType.c_ident}}*& m_tbe_ptr, Addr addr) 9557839Snilay@cs.wisc.edu{ 9568055Sksewell@umich.edu DPRINTF(RubyGenerated, "executing ${{action.ident}}\\n"); 9577839Snilay@cs.wisc.edu ${{action["c_code"]}} 9587839Snilay@cs.wisc.edu} 9597839Snilay@cs.wisc.edu 9607839Snilay@cs.wisc.edu''') 9617839Snilay@cs.wisc.edu elif self.EntryType != None: 9627839Snilay@cs.wisc.edu for action in self.actions.itervalues(): 9637839Snilay@cs.wisc.edu if "c_code" not in action: 9647839Snilay@cs.wisc.edu continue 9657839Snilay@cs.wisc.edu 9667839Snilay@cs.wisc.edu code(''' 9677839Snilay@cs.wisc.edu/** \\brief ${{action.desc}} */ 9687839Snilay@cs.wisc.eduvoid 96911025Snilay@cs.wisc.edu$c_ident::${{action.ident}}(${{self.EntryType.c_ident}}*& m_cache_entry_ptr, Addr addr) 9707839Snilay@cs.wisc.edu{ 9718055Sksewell@umich.edu DPRINTF(RubyGenerated, "executing ${{action.ident}}\\n"); 9727839Snilay@cs.wisc.edu ${{action["c_code"]}} 9737839Snilay@cs.wisc.edu} 9747839Snilay@cs.wisc.edu 9757839Snilay@cs.wisc.edu''') 9767839Snilay@cs.wisc.edu else: 9777839Snilay@cs.wisc.edu for action in self.actions.itervalues(): 9787839Snilay@cs.wisc.edu if "c_code" not in action: 9797839Snilay@cs.wisc.edu continue 9807839Snilay@cs.wisc.edu 9817839Snilay@cs.wisc.edu code(''' 9826657Snate@binkert.org/** \\brief ${{action.desc}} */ 9837007Snate@binkert.orgvoid 98411025Snilay@cs.wisc.edu$c_ident::${{action.ident}}(Addr addr) 9856657Snate@binkert.org{ 9868055Sksewell@umich.edu DPRINTF(RubyGenerated, "executing ${{action.ident}}\\n"); 9876657Snate@binkert.org ${{action["c_code"]}} 9886657Snate@binkert.org} 9896657Snate@binkert.org 9906657Snate@binkert.org''') 9918478Snilay@cs.wisc.edu for func in self.functions: 9928478Snilay@cs.wisc.edu code(func.generateCode()) 9938478Snilay@cs.wisc.edu 9949302Snilay@cs.wisc.edu # Function for functional writes to messages buffered in the controller 9959302Snilay@cs.wisc.edu code(''' 99610524Snilay@cs.wisc.eduint 9979302Snilay@cs.wisc.edu$c_ident::functionalWriteBuffers(PacketPtr& pkt) 9989302Snilay@cs.wisc.edu{ 99910524Snilay@cs.wisc.edu int num_functional_writes = 0; 10009302Snilay@cs.wisc.edu''') 10019302Snilay@cs.wisc.edu for var in self.objects: 10029302Snilay@cs.wisc.edu vtype = var.type 10039302Snilay@cs.wisc.edu if vtype.isBuffer: 100410305Snilay@cs.wisc.edu vid = "m_%s_ptr" % var.ident 10059302Snilay@cs.wisc.edu code('num_functional_writes += $vid->functionalWrite(pkt);') 100610311Snilay@cs.wisc.edu 100710311Snilay@cs.wisc.edu for var in self.config_parameters: 100810311Snilay@cs.wisc.edu vtype = var.type_ast.type 100910311Snilay@cs.wisc.edu if vtype.isBuffer: 101010311Snilay@cs.wisc.edu vid = "m_%s_ptr" % var.ident 101110311Snilay@cs.wisc.edu code('num_functional_writes += $vid->functionalWrite(pkt);') 101210311Snilay@cs.wisc.edu 10139302Snilay@cs.wisc.edu code(''' 10149302Snilay@cs.wisc.edu return num_functional_writes; 10159302Snilay@cs.wisc.edu} 10169302Snilay@cs.wisc.edu''') 10179302Snilay@cs.wisc.edu 10186657Snate@binkert.org code.write(path, "%s.cc" % c_ident) 10196657Snate@binkert.org 10209219Spower.jg@gmail.com def printCWakeup(self, path, includes): 10216657Snate@binkert.org '''Output the wakeup loop for the events''' 10226657Snate@binkert.org 10236999Snate@binkert.org code = self.symtab.codeFormatter() 10246657Snate@binkert.org ident = self.ident 10256657Snate@binkert.org 10269104Shestness@cs.utexas.edu outputRequest_types = True 10279104Shestness@cs.utexas.edu if len(self.request_types) == 0: 10289104Shestness@cs.utexas.edu outputRequest_types = False 10299104Shestness@cs.utexas.edu 10306657Snate@binkert.org code(''' 10316657Snate@binkert.org// Auto generated C++ code started by $__file__:$__line__ 10326657Snate@binkert.org// ${ident}: ${{self.short}} 10336657Snate@binkert.org 10348946Sandreas.hansson@arm.com#include <sys/types.h> 10358946Sandreas.hansson@arm.com#include <unistd.h> 10368946Sandreas.hansson@arm.com 10377832Snate@binkert.org#include <cassert> 103810972Sdavid.hashe@amd.com#include <typeinfo> 10397832Snate@binkert.org 10407007Snate@binkert.org#include "base/misc.hh" 104110972Sdavid.hashe@amd.com 104210972Sdavid.hashe@amd.com''') 104310972Sdavid.hashe@amd.com for f in self.debug_flags: 104410972Sdavid.hashe@amd.com code('#include "debug/${{f}}.hh"') 104510972Sdavid.hashe@amd.com code(''' 10468229Snate@binkert.org#include "mem/protocol/${ident}_Controller.hh" 10478229Snate@binkert.org#include "mem/protocol/${ident}_Event.hh" 10488229Snate@binkert.org#include "mem/protocol/${ident}_State.hh" 104910972Sdavid.hashe@amd.com 10509104Shestness@cs.utexas.edu''') 10519104Shestness@cs.utexas.edu 10529104Shestness@cs.utexas.edu if outputRequest_types: 10539104Shestness@cs.utexas.edu code('''#include "mem/protocol/${ident}_RequestType.hh"''') 10549104Shestness@cs.utexas.edu 10559104Shestness@cs.utexas.edu code(''' 10568229Snate@binkert.org#include "mem/protocol/Types.hh" 10576657Snate@binkert.org#include "mem/ruby/system/System.hh" 105810972Sdavid.hashe@amd.com 10599219Spower.jg@gmail.com''') 10609219Spower.jg@gmail.com 10619219Spower.jg@gmail.com 10629219Spower.jg@gmail.com for include_path in includes: 10639219Spower.jg@gmail.com code('#include "${{include_path}}"') 10649219Spower.jg@gmail.com 106510963Sdavid.hashe@amd.com port_to_buf_map, in_msg_bufs, msg_bufs = self.getBufferMaps(ident) 106610963Sdavid.hashe@amd.com 10679219Spower.jg@gmail.com code(''' 10686657Snate@binkert.org 10697055Snate@binkert.orgusing namespace std; 10707055Snate@binkert.org 10717007Snate@binkert.orgvoid 10727007Snate@binkert.org${ident}_Controller::wakeup() 10736657Snate@binkert.org{ 10746657Snate@binkert.org int counter = 0; 10756657Snate@binkert.org while (true) { 107610963Sdavid.hashe@amd.com unsigned char rejected[${{len(msg_bufs)}}]; 107710963Sdavid.hashe@amd.com memset(rejected, 0, sizeof(unsigned char)*${{len(msg_bufs)}}); 10786657Snate@binkert.org // Some cases will put us into an infinite loop without this limit 10796657Snate@binkert.org assert(counter <= m_transitions_per_cycle); 10806657Snate@binkert.org if (counter == m_transitions_per_cycle) { 10817007Snate@binkert.org // Count how often we are fully utilized 10829496Snilay@cs.wisc.edu m_fully_busy_cycles++; 10837007Snate@binkert.org 10847007Snate@binkert.org // Wakeup in another cycle and try again 10859499Snilay@cs.wisc.edu scheduleEvent(Cycles(1)); 10866657Snate@binkert.org break; 10876657Snate@binkert.org } 10886657Snate@binkert.org''') 10896657Snate@binkert.org 10906657Snate@binkert.org code.indent() 10916657Snate@binkert.org code.indent() 10926657Snate@binkert.org 10936657Snate@binkert.org # InPorts 10946657Snate@binkert.org # 10956657Snate@binkert.org for port in self.in_ports: 10966657Snate@binkert.org code.indent() 10976657Snate@binkert.org code('// ${ident}InPort $port') 10987567SBrad.Beckmann@amd.com if port.pairs.has_key("rank"): 10999996Snilay@cs.wisc.edu code('m_cur_in_port = ${{port.pairs["rank"]}};') 11007567SBrad.Beckmann@amd.com else: 11019996Snilay@cs.wisc.edu code('m_cur_in_port = 0;') 110210963Sdavid.hashe@amd.com if port in port_to_buf_map: 110310963Sdavid.hashe@amd.com code('try {') 110410963Sdavid.hashe@amd.com code.indent() 11056657Snate@binkert.org code('${{port["c_code_in_port"]}}') 110610963Sdavid.hashe@amd.com 110710963Sdavid.hashe@amd.com if port in port_to_buf_map: 110810963Sdavid.hashe@amd.com code.dedent() 110910963Sdavid.hashe@amd.com code(''' 111010963Sdavid.hashe@amd.com } catch (const RejectException & e) { 111110963Sdavid.hashe@amd.com rejected[${{port_to_buf_map[port]}}]++; 111210963Sdavid.hashe@amd.com } 111310963Sdavid.hashe@amd.com''') 11146657Snate@binkert.org code.dedent() 11156657Snate@binkert.org code('') 11166657Snate@binkert.org 11176657Snate@binkert.org code.dedent() 11186657Snate@binkert.org code.dedent() 11196657Snate@binkert.org code(''' 112010963Sdavid.hashe@amd.com // If we got this far, we have nothing left todo or something went 112110963Sdavid.hashe@amd.com // wrong''') 112210963Sdavid.hashe@amd.com for buf_name, ports in in_msg_bufs.items(): 112310963Sdavid.hashe@amd.com if len(ports) > 1: 112410963Sdavid.hashe@amd.com # only produce checks when a buffer is shared by multiple ports 112510963Sdavid.hashe@amd.com code(''' 112610963Sdavid.hashe@amd.com if (${{buf_name}}->isReady() && rejected[${{port_to_buf_map[ports[0]]}}] == ${{len(ports)}}) 112710963Sdavid.hashe@amd.com { 112810963Sdavid.hashe@amd.com // no port claimed the message on the top of this buffer 112910963Sdavid.hashe@amd.com panic("Runtime Error at Ruby Time: %d. " 113010963Sdavid.hashe@amd.com "All ports rejected a message. " 113110963Sdavid.hashe@amd.com "You are probably sending a message type to this controller " 113210963Sdavid.hashe@amd.com "over a virtual network that do not define an in_port for " 113310963Sdavid.hashe@amd.com "the incoming message type.\\n", 113410963Sdavid.hashe@amd.com Cycles(1)); 113510963Sdavid.hashe@amd.com } 113610963Sdavid.hashe@amd.com''') 113710963Sdavid.hashe@amd.com code(''' 113810963Sdavid.hashe@amd.com break; 11396657Snate@binkert.org } 11406657Snate@binkert.org} 11416657Snate@binkert.org''') 11426657Snate@binkert.org 11436657Snate@binkert.org code.write(path, "%s_Wakeup.cc" % self.ident) 11446657Snate@binkert.org 11456657Snate@binkert.org def printCSwitch(self, path): 11466657Snate@binkert.org '''Output switch statement for transition table''' 11476657Snate@binkert.org 11486999Snate@binkert.org code = self.symtab.codeFormatter() 11496657Snate@binkert.org ident = self.ident 11506657Snate@binkert.org 11516657Snate@binkert.org code(''' 11526657Snate@binkert.org// Auto generated C++ code started by $__file__:$__line__ 11536657Snate@binkert.org// ${ident}: ${{self.short}} 11546657Snate@binkert.org 11557832Snate@binkert.org#include <cassert> 11567832Snate@binkert.org 11577805Snilay@cs.wisc.edu#include "base/misc.hh" 11587832Snate@binkert.org#include "base/trace.hh" 11598232Snate@binkert.org#include "debug/ProtocolTrace.hh" 11608232Snate@binkert.org#include "debug/RubyGenerated.hh" 11618229Snate@binkert.org#include "mem/protocol/${ident}_Controller.hh" 11628229Snate@binkert.org#include "mem/protocol/${ident}_Event.hh" 11638229Snate@binkert.org#include "mem/protocol/${ident}_State.hh" 11648229Snate@binkert.org#include "mem/protocol/Types.hh" 11656657Snate@binkert.org#include "mem/ruby/system/System.hh" 11666657Snate@binkert.org 11676657Snate@binkert.org#define HASH_FUN(state, event) ((int(state)*${ident}_Event_NUM)+int(event)) 11686657Snate@binkert.org 11696657Snate@binkert.org#define GET_TRANSITION_COMMENT() (${ident}_transitionComment.str()) 11706657Snate@binkert.org#define CLEAR_TRANSITION_COMMENT() (${ident}_transitionComment.str("")) 11716657Snate@binkert.org 11727007Snate@binkert.orgTransitionResult 11737007Snate@binkert.org${ident}_Controller::doTransition(${ident}_Event event, 11747839Snilay@cs.wisc.edu''') 11757839Snilay@cs.wisc.edu if self.EntryType != None: 11767839Snilay@cs.wisc.edu code(''' 11777839Snilay@cs.wisc.edu ${{self.EntryType.c_ident}}* m_cache_entry_ptr, 11787839Snilay@cs.wisc.edu''') 11797839Snilay@cs.wisc.edu if self.TBEType != None: 11807839Snilay@cs.wisc.edu code(''' 11817839Snilay@cs.wisc.edu ${{self.TBEType.c_ident}}* m_tbe_ptr, 11827839Snilay@cs.wisc.edu''') 11837839Snilay@cs.wisc.edu code(''' 118411025Snilay@cs.wisc.edu Addr addr) 11856657Snate@binkert.org{ 11867839Snilay@cs.wisc.edu''') 118710305Snilay@cs.wisc.edu code.indent() 118810305Snilay@cs.wisc.edu 11897839Snilay@cs.wisc.edu if self.TBEType != None and self.EntryType != None: 11908337Snilay@cs.wisc.edu code('${ident}_State state = getState(m_tbe_ptr, m_cache_entry_ptr, addr);') 11917839Snilay@cs.wisc.edu elif self.TBEType != None: 11928337Snilay@cs.wisc.edu code('${ident}_State state = getState(m_tbe_ptr, addr);') 11937839Snilay@cs.wisc.edu elif self.EntryType != None: 11948337Snilay@cs.wisc.edu code('${ident}_State state = getState(m_cache_entry_ptr, addr);') 11957839Snilay@cs.wisc.edu else: 11968337Snilay@cs.wisc.edu code('${ident}_State state = getState(addr);') 11977839Snilay@cs.wisc.edu 11987839Snilay@cs.wisc.edu code(''' 119910305Snilay@cs.wisc.edu${ident}_State next_state = state; 12006657Snate@binkert.org 120110305Snilay@cs.wisc.eduDPRINTF(RubyGenerated, "%s, Time: %lld, state: %s, event: %s, addr: %s\\n", 120210305Snilay@cs.wisc.edu *this, curCycle(), ${ident}_State_to_string(state), 120310305Snilay@cs.wisc.edu ${ident}_Event_to_string(event), addr); 12046657Snate@binkert.org 120510305Snilay@cs.wisc.eduTransitionResult result = 12067839Snilay@cs.wisc.edu''') 12077839Snilay@cs.wisc.edu if self.TBEType != None and self.EntryType != None: 12087839Snilay@cs.wisc.edu code('doTransitionWorker(event, state, next_state, m_tbe_ptr, m_cache_entry_ptr, addr);') 12097839Snilay@cs.wisc.edu elif self.TBEType != None: 12107839Snilay@cs.wisc.edu code('doTransitionWorker(event, state, next_state, m_tbe_ptr, addr);') 12117839Snilay@cs.wisc.edu elif self.EntryType != None: 12127839Snilay@cs.wisc.edu code('doTransitionWorker(event, state, next_state, m_cache_entry_ptr, addr);') 12137839Snilay@cs.wisc.edu else: 12147839Snilay@cs.wisc.edu code('doTransitionWorker(event, state, next_state, addr);') 12156657Snate@binkert.org 121611049Snilay@cs.wisc.edu port_to_buf_map, in_msg_bufs, msg_bufs = self.getBufferMaps(ident) 121711049Snilay@cs.wisc.edu 12187839Snilay@cs.wisc.edu code(''' 12196657Snate@binkert.org 122010305Snilay@cs.wisc.eduif (result == TransitionResult_Valid) { 122110305Snilay@cs.wisc.edu DPRINTF(RubyGenerated, "next_state: %s\\n", 122210305Snilay@cs.wisc.edu ${ident}_State_to_string(next_state)); 122310305Snilay@cs.wisc.edu countTransition(state, event); 122410305Snilay@cs.wisc.edu 122511025Snilay@cs.wisc.edu DPRINTFR(ProtocolTrace, "%15d %3s %10s%20s %6s>%-6s %#x %s\\n", 122610305Snilay@cs.wisc.edu curTick(), m_version, "${ident}", 122710305Snilay@cs.wisc.edu ${ident}_Event_to_string(event), 122810305Snilay@cs.wisc.edu ${ident}_State_to_string(state), 122910305Snilay@cs.wisc.edu ${ident}_State_to_string(next_state), 123010305Snilay@cs.wisc.edu addr, GET_TRANSITION_COMMENT()); 123110305Snilay@cs.wisc.edu 123210305Snilay@cs.wisc.edu CLEAR_TRANSITION_COMMENT(); 12337839Snilay@cs.wisc.edu''') 12347839Snilay@cs.wisc.edu if self.TBEType != None and self.EntryType != None: 12358337Snilay@cs.wisc.edu code('setState(m_tbe_ptr, m_cache_entry_ptr, addr, next_state);') 12368341Snilay@cs.wisc.edu code('setAccessPermission(m_cache_entry_ptr, addr, next_state);') 12377839Snilay@cs.wisc.edu elif self.TBEType != None: 12388337Snilay@cs.wisc.edu code('setState(m_tbe_ptr, addr, next_state);') 12398341Snilay@cs.wisc.edu code('setAccessPermission(addr, next_state);') 12407839Snilay@cs.wisc.edu elif self.EntryType != None: 12418337Snilay@cs.wisc.edu code('setState(m_cache_entry_ptr, addr, next_state);') 12428341Snilay@cs.wisc.edu code('setAccessPermission(m_cache_entry_ptr, addr, next_state);') 12437839Snilay@cs.wisc.edu else: 12448337Snilay@cs.wisc.edu code('setState(addr, next_state);') 12458341Snilay@cs.wisc.edu code('setAccessPermission(addr, next_state);') 12467839Snilay@cs.wisc.edu 12477839Snilay@cs.wisc.edu code(''' 124810305Snilay@cs.wisc.edu} else if (result == TransitionResult_ResourceStall) { 124911025Snilay@cs.wisc.edu DPRINTFR(ProtocolTrace, "%15s %3s %10s%20s %6s>%-6s %#x %s\\n", 125010305Snilay@cs.wisc.edu curTick(), m_version, "${ident}", 125110305Snilay@cs.wisc.edu ${ident}_Event_to_string(event), 125210305Snilay@cs.wisc.edu ${ident}_State_to_string(state), 125310305Snilay@cs.wisc.edu ${ident}_State_to_string(next_state), 125410305Snilay@cs.wisc.edu addr, "Resource Stall"); 125510305Snilay@cs.wisc.edu} else if (result == TransitionResult_ProtocolStall) { 125610305Snilay@cs.wisc.edu DPRINTF(RubyGenerated, "stalling\\n"); 125711025Snilay@cs.wisc.edu DPRINTFR(ProtocolTrace, "%15s %3s %10s%20s %6s>%-6s %#x %s\\n", 125810305Snilay@cs.wisc.edu curTick(), m_version, "${ident}", 125910305Snilay@cs.wisc.edu ${ident}_Event_to_string(event), 126010305Snilay@cs.wisc.edu ${ident}_State_to_string(state), 126110305Snilay@cs.wisc.edu ${ident}_State_to_string(next_state), 126210305Snilay@cs.wisc.edu addr, "Protocol Stall"); 126310305Snilay@cs.wisc.edu} 12646657Snate@binkert.org 126510305Snilay@cs.wisc.edureturn result; 126610305Snilay@cs.wisc.edu''') 126710305Snilay@cs.wisc.edu code.dedent() 126810305Snilay@cs.wisc.edu code(''' 12696657Snate@binkert.org} 12706657Snate@binkert.org 12717007Snate@binkert.orgTransitionResult 12727007Snate@binkert.org${ident}_Controller::doTransitionWorker(${ident}_Event event, 12737007Snate@binkert.org ${ident}_State state, 12747007Snate@binkert.org ${ident}_State& next_state, 12757839Snilay@cs.wisc.edu''') 12767839Snilay@cs.wisc.edu 12777839Snilay@cs.wisc.edu if self.TBEType != None: 12787839Snilay@cs.wisc.edu code(''' 12797839Snilay@cs.wisc.edu ${{self.TBEType.c_ident}}*& m_tbe_ptr, 12807839Snilay@cs.wisc.edu''') 12817839Snilay@cs.wisc.edu if self.EntryType != None: 12827839Snilay@cs.wisc.edu code(''' 12837839Snilay@cs.wisc.edu ${{self.EntryType.c_ident}}*& m_cache_entry_ptr, 12847839Snilay@cs.wisc.edu''') 12857839Snilay@cs.wisc.edu code(''' 128611025Snilay@cs.wisc.edu Addr addr) 12876657Snate@binkert.org{ 12886657Snate@binkert.org switch(HASH_FUN(state, event)) { 12896657Snate@binkert.org''') 12906657Snate@binkert.org 12916657Snate@binkert.org # This map will allow suppress generating duplicate code 12926657Snate@binkert.org cases = orderdict() 12936657Snate@binkert.org 12946657Snate@binkert.org for trans in self.transitions: 12956657Snate@binkert.org case_string = "%s_State_%s, %s_Event_%s" % \ 12966657Snate@binkert.org (self.ident, trans.state.ident, self.ident, trans.event.ident) 12976657Snate@binkert.org 12986999Snate@binkert.org case = self.symtab.codeFormatter() 12996657Snate@binkert.org # Only set next_state if it changes 13006657Snate@binkert.org if trans.state != trans.nextState: 130110964Sdavid.hashe@amd.com if trans.nextState.isWildcard(): 130210964Sdavid.hashe@amd.com # When * is encountered as an end state of a transition, 130310964Sdavid.hashe@amd.com # the next state is determined by calling the 130410964Sdavid.hashe@amd.com # machine-specific getNextState function. The next state 130510964Sdavid.hashe@amd.com # is determined before any actions of the transition 130610964Sdavid.hashe@amd.com # execute, and therefore the next state calculation cannot 130710964Sdavid.hashe@amd.com # depend on any of the transitionactions. 130810964Sdavid.hashe@amd.com case('next_state = getNextState(addr);') 130910964Sdavid.hashe@amd.com else: 131010964Sdavid.hashe@amd.com ns_ident = trans.nextState.ident 131110964Sdavid.hashe@amd.com case('next_state = ${ident}_State_${ns_ident};') 13126657Snate@binkert.org 13136657Snate@binkert.org actions = trans.actions 13149104Shestness@cs.utexas.edu request_types = trans.request_types 13156657Snate@binkert.org 13166657Snate@binkert.org # Check for resources 13176657Snate@binkert.org case_sorter = [] 13186657Snate@binkert.org res = trans.resources 13196657Snate@binkert.org for key,val in res.iteritems(): 132010228Snilay@cs.wisc.edu val = ''' 13217007Snate@binkert.orgif (!%s.areNSlotsAvailable(%s)) 13226657Snate@binkert.org return TransitionResult_ResourceStall; 13236657Snate@binkert.org''' % (key.code, val) 13246657Snate@binkert.org case_sorter.append(val) 13256657Snate@binkert.org 13269105SBrad.Beckmann@amd.com # Check all of the request_types for resource constraints 13279105SBrad.Beckmann@amd.com for request_type in request_types: 13289105SBrad.Beckmann@amd.com val = ''' 13299105SBrad.Beckmann@amd.comif (!checkResourceAvailable(%s_RequestType_%s, addr)) { 13309105SBrad.Beckmann@amd.com return TransitionResult_ResourceStall; 13319105SBrad.Beckmann@amd.com} 13329105SBrad.Beckmann@amd.com''' % (self.ident, request_type.ident) 13339105SBrad.Beckmann@amd.com case_sorter.append(val) 13346657Snate@binkert.org 13356657Snate@binkert.org # Emit the code sequences in a sorted order. This makes the 13366657Snate@binkert.org # output deterministic (without this the output order can vary 13376657Snate@binkert.org # since Map's keys() on a vector of pointers is not deterministic 13386657Snate@binkert.org for c in sorted(case_sorter): 13396657Snate@binkert.org case("$c") 13406657Snate@binkert.org 13419104Shestness@cs.utexas.edu # Record access types for this transition 13429104Shestness@cs.utexas.edu for request_type in request_types: 13439104Shestness@cs.utexas.edu case('recordRequestType(${ident}_RequestType_${{request_type.ident}}, addr);') 13449104Shestness@cs.utexas.edu 13456657Snate@binkert.org # Figure out if we stall 13466657Snate@binkert.org stall = False 13476657Snate@binkert.org for action in actions: 13486657Snate@binkert.org if action.ident == "z_stall": 13496657Snate@binkert.org stall = True 13506657Snate@binkert.org break 13516657Snate@binkert.org 13526657Snate@binkert.org if stall: 13536657Snate@binkert.org case('return TransitionResult_ProtocolStall;') 13546657Snate@binkert.org else: 13557839Snilay@cs.wisc.edu if self.TBEType != None and self.EntryType != None: 13567839Snilay@cs.wisc.edu for action in actions: 13577839Snilay@cs.wisc.edu case('${{action.ident}}(m_tbe_ptr, m_cache_entry_ptr, addr);') 13587839Snilay@cs.wisc.edu elif self.TBEType != None: 13597839Snilay@cs.wisc.edu for action in actions: 13607839Snilay@cs.wisc.edu case('${{action.ident}}(m_tbe_ptr, addr);') 13617839Snilay@cs.wisc.edu elif self.EntryType != None: 13627839Snilay@cs.wisc.edu for action in actions: 13637839Snilay@cs.wisc.edu case('${{action.ident}}(m_cache_entry_ptr, addr);') 13647839Snilay@cs.wisc.edu else: 13657839Snilay@cs.wisc.edu for action in actions: 13667839Snilay@cs.wisc.edu case('${{action.ident}}(addr);') 13676657Snate@binkert.org case('return TransitionResult_Valid;') 13686657Snate@binkert.org 13696657Snate@binkert.org case = str(case) 13706657Snate@binkert.org 13716657Snate@binkert.org # Look to see if this transition code is unique. 13726657Snate@binkert.org if case not in cases: 13736657Snate@binkert.org cases[case] = [] 13746657Snate@binkert.org 13756657Snate@binkert.org cases[case].append(case_string) 13766657Snate@binkert.org 13776657Snate@binkert.org # Walk through all of the unique code blocks and spit out the 13786657Snate@binkert.org # corresponding case statement elements 13796657Snate@binkert.org for case,transitions in cases.iteritems(): 13806657Snate@binkert.org # Iterative over all the multiple transitions that share 13816657Snate@binkert.org # the same code 13826657Snate@binkert.org for trans in transitions: 13836657Snate@binkert.org code(' case HASH_FUN($trans):') 138410305Snilay@cs.wisc.edu code(' $case\n') 13856657Snate@binkert.org 13866657Snate@binkert.org code(''' 13876657Snate@binkert.org default: 138810962SBrad.Beckmann@amd.com panic("Invalid transition\\n" 13898159SBrad.Beckmann@amd.com "%s time: %d addr: %s event: %s state: %s\\n", 13909465Snilay@cs.wisc.edu name(), curCycle(), addr, event, state); 13916657Snate@binkert.org } 139210305Snilay@cs.wisc.edu 13936657Snate@binkert.org return TransitionResult_Valid; 13946657Snate@binkert.org} 13956657Snate@binkert.org''') 13966657Snate@binkert.org code.write(path, "%s_Transitions.cc" % self.ident) 13976657Snate@binkert.org 13986657Snate@binkert.org 13996657Snate@binkert.org # ************************** 14006657Snate@binkert.org # ******* HTML Files ******* 14016657Snate@binkert.org # ************************** 14027007Snate@binkert.org def frameRef(self, click_href, click_target, over_href, over_num, text): 14036999Snate@binkert.org code = self.symtab.codeFormatter(fix_newlines=False) 14047007Snate@binkert.org code("""<A href=\"$click_href\" target=\"$click_target\" onmouseover=\" 14057007Snate@binkert.org if (parent.frames[$over_num].location != parent.location + '$over_href') { 14067007Snate@binkert.org parent.frames[$over_num].location='$over_href' 14077007Snate@binkert.org }\"> 14087007Snate@binkert.org ${{html.formatShorthand(text)}} 14097007Snate@binkert.org </A>""") 14106657Snate@binkert.org return str(code) 14116657Snate@binkert.org 14126657Snate@binkert.org def writeHTMLFiles(self, path): 14136657Snate@binkert.org # Create table with no row hilighted 14146657Snate@binkert.org self.printHTMLTransitions(path, None) 14156657Snate@binkert.org 14166657Snate@binkert.org # Generate transition tables 14176657Snate@binkert.org for state in self.states.itervalues(): 14186657Snate@binkert.org self.printHTMLTransitions(path, state) 14196657Snate@binkert.org 14206657Snate@binkert.org # Generate action descriptions 14216657Snate@binkert.org for action in self.actions.itervalues(): 14226657Snate@binkert.org name = "%s_action_%s.html" % (self.ident, action.ident) 14236657Snate@binkert.org code = html.createSymbol(action, "Action") 14246657Snate@binkert.org code.write(path, name) 14256657Snate@binkert.org 14266657Snate@binkert.org # Generate state descriptions 14276657Snate@binkert.org for state in self.states.itervalues(): 14286657Snate@binkert.org name = "%s_State_%s.html" % (self.ident, state.ident) 14296657Snate@binkert.org code = html.createSymbol(state, "State") 14306657Snate@binkert.org code.write(path, name) 14316657Snate@binkert.org 14326657Snate@binkert.org # Generate event descriptions 14336657Snate@binkert.org for event in self.events.itervalues(): 14346657Snate@binkert.org name = "%s_Event_%s.html" % (self.ident, event.ident) 14356657Snate@binkert.org code = html.createSymbol(event, "Event") 14366657Snate@binkert.org code.write(path, name) 14376657Snate@binkert.org 14386657Snate@binkert.org def printHTMLTransitions(self, path, active_state): 14396999Snate@binkert.org code = self.symtab.codeFormatter() 14406657Snate@binkert.org 14416657Snate@binkert.org code(''' 14427007Snate@binkert.org<HTML> 14437007Snate@binkert.org<BODY link="blue" vlink="blue"> 14446657Snate@binkert.org 14456657Snate@binkert.org<H1 align="center">${{html.formatShorthand(self.short)}}: 14466657Snate@binkert.org''') 14476657Snate@binkert.org code.indent() 14486657Snate@binkert.org for i,machine in enumerate(self.symtab.getAllType(StateMachine)): 14496657Snate@binkert.org mid = machine.ident 14506657Snate@binkert.org if i != 0: 14516657Snate@binkert.org extra = " - " 14526657Snate@binkert.org else: 14536657Snate@binkert.org extra = "" 14546657Snate@binkert.org if machine == self: 14556657Snate@binkert.org code('$extra$mid') 14566657Snate@binkert.org else: 14576657Snate@binkert.org code('$extra<A target="Table" href="${mid}_table.html">$mid</A>') 14586657Snate@binkert.org code.dedent() 14596657Snate@binkert.org 14606657Snate@binkert.org code(""" 14616657Snate@binkert.org</H1> 14626657Snate@binkert.org 14636657Snate@binkert.org<TABLE border=1> 14646657Snate@binkert.org<TR> 14656657Snate@binkert.org <TH> </TH> 14666657Snate@binkert.org""") 14676657Snate@binkert.org 14686657Snate@binkert.org for event in self.events.itervalues(): 14696657Snate@binkert.org href = "%s_Event_%s.html" % (self.ident, event.ident) 14706657Snate@binkert.org ref = self.frameRef(href, "Status", href, "1", event.short) 14716657Snate@binkert.org code('<TH bgcolor=white>$ref</TH>') 14726657Snate@binkert.org 14736657Snate@binkert.org code('</TR>') 14746657Snate@binkert.org # -- Body of table 14756657Snate@binkert.org for state in self.states.itervalues(): 14766657Snate@binkert.org # -- Each row 14776657Snate@binkert.org if state == active_state: 14786657Snate@binkert.org color = "yellow" 14796657Snate@binkert.org else: 14806657Snate@binkert.org color = "white" 14816657Snate@binkert.org 14826657Snate@binkert.org click = "%s_table_%s.html" % (self.ident, state.ident) 14836657Snate@binkert.org over = "%s_State_%s.html" % (self.ident, state.ident) 14846657Snate@binkert.org text = html.formatShorthand(state.short) 14856657Snate@binkert.org ref = self.frameRef(click, "Table", over, "1", state.short) 14866657Snate@binkert.org code(''' 14876657Snate@binkert.org<TR> 14886657Snate@binkert.org <TH bgcolor=$color>$ref</TH> 14896657Snate@binkert.org''') 14906657Snate@binkert.org 14916657Snate@binkert.org # -- One column for each event 14926657Snate@binkert.org for event in self.events.itervalues(): 14936657Snate@binkert.org trans = self.table.get((state,event), None) 14946657Snate@binkert.org if trans is None: 14956657Snate@binkert.org # This is the no transition case 14966657Snate@binkert.org if state == active_state: 14976657Snate@binkert.org color = "#C0C000" 14986657Snate@binkert.org else: 14996657Snate@binkert.org color = "lightgrey" 15006657Snate@binkert.org 15016657Snate@binkert.org code('<TD bgcolor=$color> </TD>') 15026657Snate@binkert.org continue 15036657Snate@binkert.org 15046657Snate@binkert.org next = trans.nextState 15056657Snate@binkert.org stall_action = False 15066657Snate@binkert.org 15076657Snate@binkert.org # -- Get the actions 15086657Snate@binkert.org for action in trans.actions: 15096657Snate@binkert.org if action.ident == "z_stall" or \ 15106657Snate@binkert.org action.ident == "zz_recycleMandatoryQueue": 15116657Snate@binkert.org stall_action = True 15126657Snate@binkert.org 15136657Snate@binkert.org # -- Print out "actions/next-state" 15146657Snate@binkert.org if stall_action: 15156657Snate@binkert.org if state == active_state: 15166657Snate@binkert.org color = "#C0C000" 15176657Snate@binkert.org else: 15186657Snate@binkert.org color = "lightgrey" 15196657Snate@binkert.org 15206657Snate@binkert.org elif active_state and next.ident == active_state.ident: 15216657Snate@binkert.org color = "aqua" 15226657Snate@binkert.org elif state == active_state: 15236657Snate@binkert.org color = "yellow" 15246657Snate@binkert.org else: 15256657Snate@binkert.org color = "white" 15266657Snate@binkert.org 15276657Snate@binkert.org code('<TD bgcolor=$color>') 15286657Snate@binkert.org for action in trans.actions: 15296657Snate@binkert.org href = "%s_action_%s.html" % (self.ident, action.ident) 15306657Snate@binkert.org ref = self.frameRef(href, "Status", href, "1", 15316657Snate@binkert.org action.short) 15327007Snate@binkert.org code(' $ref') 15336657Snate@binkert.org if next != state: 15346657Snate@binkert.org if trans.actions: 15356657Snate@binkert.org code('/') 15366657Snate@binkert.org click = "%s_table_%s.html" % (self.ident, next.ident) 15376657Snate@binkert.org over = "%s_State_%s.html" % (self.ident, next.ident) 15386657Snate@binkert.org ref = self.frameRef(click, "Table", over, "1", next.short) 15396657Snate@binkert.org code("$ref") 15407007Snate@binkert.org code("</TD>") 15416657Snate@binkert.org 15426657Snate@binkert.org # -- Each row 15436657Snate@binkert.org if state == active_state: 15446657Snate@binkert.org color = "yellow" 15456657Snate@binkert.org else: 15466657Snate@binkert.org color = "white" 15476657Snate@binkert.org 15486657Snate@binkert.org click = "%s_table_%s.html" % (self.ident, state.ident) 15496657Snate@binkert.org over = "%s_State_%s.html" % (self.ident, state.ident) 15506657Snate@binkert.org ref = self.frameRef(click, "Table", over, "1", state.short) 15516657Snate@binkert.org code(''' 15526657Snate@binkert.org <TH bgcolor=$color>$ref</TH> 15536657Snate@binkert.org</TR> 15546657Snate@binkert.org''') 15556657Snate@binkert.org code(''' 155610917Sbrandon.potter@amd.com<!- Column footer-> 15576657Snate@binkert.org<TR> 15586657Snate@binkert.org <TH> </TH> 15596657Snate@binkert.org''') 15606657Snate@binkert.org 15616657Snate@binkert.org for event in self.events.itervalues(): 15626657Snate@binkert.org href = "%s_Event_%s.html" % (self.ident, event.ident) 15636657Snate@binkert.org ref = self.frameRef(href, "Status", href, "1", event.short) 15646657Snate@binkert.org code('<TH bgcolor=white>$ref</TH>') 15656657Snate@binkert.org code(''' 15666657Snate@binkert.org</TR> 15676657Snate@binkert.org</TABLE> 15686657Snate@binkert.org</BODY></HTML> 15696657Snate@binkert.org''') 15706657Snate@binkert.org 15716657Snate@binkert.org 15726657Snate@binkert.org if active_state: 15736657Snate@binkert.org name = "%s_table_%s.html" % (self.ident, active_state.ident) 15746657Snate@binkert.org else: 15756657Snate@binkert.org name = "%s_table.html" % self.ident 15766657Snate@binkert.org code.write(path, name) 15776657Snate@binkert.org 15786657Snate@binkert.org__all__ = [ "StateMachine" ] 1579