summaryrefslogtreecommitdiff
path: root/src/mem/slicc/symbols
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/slicc/symbols')
-rw-r--r--src/mem/slicc/symbols/Action.hh52
-rw-r--r--src/mem/slicc/symbols/Action.py38
-rw-r--r--src/mem/slicc/symbols/Event.hh45
-rw-r--r--src/mem/slicc/symbols/Event.py34
-rw-r--r--src/mem/slicc/symbols/Func.cc143
-rw-r--r--src/mem/slicc/symbols/Func.hh96
-rw-r--r--src/mem/slicc/symbols/Func.py107
-rw-r--r--src/mem/slicc/symbols/State.hh45
-rw-r--r--src/mem/slicc/symbols/State.py34
-rw-r--r--src/mem/slicc/symbols/StateMachine.cc1534
-rw-r--r--src/mem/slicc/symbols/StateMachine.hh156
-rw-r--r--src/mem/slicc/symbols/StateMachine.py1222
-rw-r--r--src/mem/slicc/symbols/Symbol.cc72
-rw-r--r--src/mem/slicc/symbols/Symbol.hh100
-rw-r--r--src/mem/slicc/symbols/Symbol.py78
-rw-r--r--src/mem/slicc/symbols/SymbolTable.cc327
-rw-r--r--src/mem/slicc/symbols/SymbolTable.hh121
-rw-r--r--src/mem/slicc/symbols/SymbolTable.py218
-rw-r--r--src/mem/slicc/symbols/Transition.cc173
-rw-r--r--src/mem/slicc/symbols/Transition.hh120
-rw-r--r--src/mem/slicc/symbols/Transition.py61
-rw-r--r--src/mem/slicc/symbols/Type.cc779
-rw-r--r--src/mem/slicc/symbols/Type.hh155
-rw-r--r--src/mem/slicc/symbols/Type.py650
-rw-r--r--src/mem/slicc/symbols/Var.cc57
-rw-r--r--src/mem/slicc/symbols/Var.hh98
-rw-r--r--src/mem/slicc/symbols/Var.py50
-rw-r--r--src/mem/slicc/symbols/__init__.py38
28 files changed, 2530 insertions, 4073 deletions
diff --git a/src/mem/slicc/symbols/Action.hh b/src/mem/slicc/symbols/Action.hh
deleted file mode 100644
index dbb0c836a..000000000
--- a/src/mem/slicc/symbols/Action.hh
+++ /dev/null
@@ -1,52 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- */
-
-#ifndef ACTION_H
-#define ACTION_H
-
-#include "mem/slicc/symbols/Symbol.hh"
-
-class Action : public Symbol {
-public:
- Action(string id,
- const Map<Var*, string>& resources,
- const Location& location,
- const Map<string, string>& pairs) : Symbol(id, location, pairs) { m_resources = resources; }
- const Map<Var*, string>& getResources() const { return m_resources; }
- void print(ostream& out) const { out << "[Action: " << getIdent() << "]"; }
-
-private:
- Map<Var*, string> m_resources;
-};
-
-#endif //ACTION_H
diff --git a/src/mem/slicc/symbols/Action.py b/src/mem/slicc/symbols/Action.py
new file mode 100644
index 000000000..880fab15a
--- /dev/null
+++ b/src/mem/slicc/symbols/Action.py
@@ -0,0 +1,38 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.symbols.Symbol import Symbol
+
+class Action(Symbol):
+ def __init__(self, table, ident, resources, location, pairs):
+ super(Action, self).__init__(table, ident, location, pairs)
+ self.resources = resources
+
+ def __repr__(self):
+ return "[Action: %s]" % self.ident
+
+__all__ = [ "Action" ]
diff --git a/src/mem/slicc/symbols/Event.hh b/src/mem/slicc/symbols/Event.hh
deleted file mode 100644
index 40cefc982..000000000
--- a/src/mem/slicc/symbols/Event.hh
+++ /dev/null
@@ -1,45 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- */
-
-#ifndef EVENT_H
-#define EVENT_H
-
-#include "mem/slicc/symbols/Symbol.hh"
-
-class Event : public Symbol {
-public:
- Event(string id, const Location& location, const Map<string, string>& pairs) : Symbol(id, location, pairs) {}
- void print(ostream& out) const { out << "[Event: " << getIdent() << "]"; }
-};
-
-#endif //EVENT_H
diff --git a/src/mem/slicc/symbols/Event.py b/src/mem/slicc/symbols/Event.py
new file mode 100644
index 000000000..9ff4d8ba7
--- /dev/null
+++ b/src/mem/slicc/symbols/Event.py
@@ -0,0 +1,34 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.symbols.Symbol import Symbol
+
+class Event(Symbol):
+ def __repr__(self):
+ return "[Event: %s]" % self.ident
+
+__all__ = [ "Event" ]
diff --git a/src/mem/slicc/symbols/Func.cc b/src/mem/slicc/symbols/Func.cc
deleted file mode 100644
index d29138b38..000000000
--- a/src/mem/slicc/symbols/Func.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Func.cc
- *
- * Description: See Func.hh
- *
- * $Id$
- *
- */
-
-#include "mem/slicc/symbols/Func.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-#include "mem/slicc/generator/fileio.hh"
-#include "mem/slicc/symbols/StateMachine.hh"
-
-Func::Func(string id, const Location& location,
- Type* type_ptr, const Vector<Type*>& param_type_vec,
- const Vector<string>& param_string_vec, string body,
- const Map<string, string>& pairs, StateMachine* machine_ptr)
- : Symbol(id, location, pairs)
-{
- m_type_ptr = type_ptr;
- m_param_type_vec = param_type_vec;
- m_param_string_vec = param_string_vec;
- m_body = body;
- m_isInternalMachineFunc = false;
-
- if (machine_ptr == NULL) {
- m_c_ident = id;
- } else if (existPair("external") || existPair("primitive")) {
- m_c_ident = id;
- } else {
- m_machineStr = machine_ptr->toString();
- m_c_ident = m_machineStr + "_" + id; // Append with machine name
- m_isInternalMachineFunc = true;
- }
-}
-
-void Func::funcPrototype(string& code) const
-{
- if (isExternal()) {
- // Do nothing
- } else {
- string return_type = m_type_ptr->cIdent();
- Type* void_type_ptr = g_sym_table.getType("void");
- if (existPair("return_by_ref") && (m_type_ptr != void_type_ptr)) {
- return_type += "&";
- }
- code += return_type + " " + cIdent() + "(";
- int size = m_param_string_vec.size();
- for(int i=0; i<size; i++) {
- // Generate code
- if (i != 0) {
- code += ", ";
- }
- code += m_param_string_vec[i];
- }
- code += ");\n";
- }
-}
-
-// This write a function of object Chip
-void Func::writeCFiles(string path)
-{
- if (isExternal()) {
- // Do nothing
- } else {
- ostringstream out;
-
- // Header
- out << "/** Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< " */" << endl;
- out << endl;
- out << "#include \"mem/protocol/Types.hh\"" << endl;
- if (m_isInternalMachineFunc) {
- out << "#include \"mem/protocol/" << m_machineStr << "_Controller.hh\"" << endl;
- }
- out << endl;
-
- // Generate function header
- string code;
- Type* void_type_ptr = g_sym_table.getType("void");
- string return_type = m_type_ptr->cIdent();
- code += return_type;
- if (existPair("return_by_ref") && m_type_ptr != void_type_ptr) {
- code += "&";
- }
- if (!m_isInternalMachineFunc) {
- code += " Chip::" + cIdent() + "(";
- } else {
- code += " " + m_machineStr + "_Controller::" + cIdent() + "(";
- }
- int size = m_param_type_vec.size();
- for(int i=0; i<size; i++) {
- // Generate code
- if (i != 0) {
- code += ", ";
- }
- code += m_param_string_vec[i];
- }
- code += ")";
-
- // Function body
- code += "\n{\n";
- code += m_body;
- code += "}\n";
- out << code << endl;
-
- // Write it out
- conditionally_write_file(path + cIdent() + ".cc", out);
- }
-}
-
-void Func::print(ostream& out) const
-{
-}
diff --git a/src/mem/slicc/symbols/Func.hh b/src/mem/slicc/symbols/Func.hh
deleted file mode 100644
index 8f8548bb0..000000000
--- a/src/mem/slicc/symbols/Func.hh
+++ /dev/null
@@ -1,96 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Func.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef FUNC_H
-#define FUNC_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/symbols/Type.hh"
-class StateMachine;
-
-class Func : public Symbol {
-public:
- // Constructors
- Func(string id, const Location& location,
- Type* type_ptr, const Vector<Type*>& param_type_vec, const Vector<string>& param_string_vec,
- string body, const Map<string, string>& pairs, StateMachine* machine_ptr);
-
- // Destructor
- ~Func() {}
-
- // Public Methods
- string cIdent() const { return m_c_ident; }
- const Vector<Type*>& getParamTypes() const { return m_param_type_vec; }
- Type* getReturnType() const { return m_type_ptr; }
- void writeCFiles(string path) ;
- void funcPrototype(string& code) const;
- bool isExternal() const { return existPair("external"); }
- bool isInternalMachineFunc() const { return m_isInternalMachineFunc; }
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- Func(const Func& obj);
- Func& operator=(const Func& obj);
-
- // Data Members (m_ prefix)
- Type* m_type_ptr;
- Vector<Type*> m_param_type_vec;
- Vector<string> m_param_string_vec;
- string m_body;
- string m_c_ident;
- string m_machineStr;
- bool m_isInternalMachineFunc;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const Func& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const Func& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //FUNC_H
diff --git a/src/mem/slicc/symbols/Func.py b/src/mem/slicc/symbols/Func.py
new file mode 100644
index 000000000..5c812a96f
--- /dev/null
+++ b/src/mem/slicc/symbols/Func.py
@@ -0,0 +1,107 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter
+
+from slicc.symbols.Symbol import Symbol
+from slicc.symbols.Type import Type
+
+class Func(Symbol):
+ def __init__(self, table, ident, location, return_type, param_types,
+ param_strings, body, pairs, machine):
+ super(Func, self).__init__(table, ident, location, pairs)
+ self.return_type = return_type
+ self.param_types = param_types
+ self.param_strings = param_strings
+ self.body = body
+ self.isInternalMachineFunc = False
+
+ if machine is None:
+ self.c_ident = ident
+ elif "external" in self or "primitive" in self:
+ self.c_ident = ident
+ else:
+ self.machineStr = str(machine)
+ # Append with machine name
+ self.c_ident = "%s_%s" % (self.machineStr, ident)
+ self.isInternalMachineFunc = True
+
+ def __repr__(self):
+ return ""
+
+ @property
+ def prototype(self):
+ if "external" in self:
+ return ""
+
+ return_type = self.return_type.c_ident
+ void_type = self.symtab.find("void", Type)
+ if "return_by_ref" in self and self.return_type != void_type:
+ return_type += "&"
+
+ return "%s %s(%s);" % (return_type, self.c_ident,
+ ", ".join(self.param_strings))
+
+ def writeCodeFiles(self, path):
+ '''This write a function of object Chip'''
+ if "external" in self:
+ return
+
+ code = code_formatter()
+
+ # Header
+ code('''
+/** Auto generated C++ code started by $__file__:$__line__ */
+
+#include "mem/protocol/Types.hh"
+''')
+
+ if self.isInternalMachineFunc:
+ code('#include "mem/protocol/${{self.machineStr}}_Controller.hh"')
+
+ # Generate function header
+ void_type = self.symtab.find("void", Type)
+ return_type = self.return_type.c_ident
+ if "return_by_ref" in self and self.return_type != void_type:
+ return_type += "&"
+
+ if self.isInternalMachineFunc:
+ klass = "%s_Controller" % self.machineStr
+ else:
+ klass = "Chip"
+
+ params = ', '.join(self.param_strings)
+
+ code('''
+$return_type ${klass}::${{self.c_ident}}($params)
+{
+${{self.body}}
+}
+''')
+ code.write(path, "%s.cc" % self.c_ident)
+
+__all__ = [ "Func" ]
diff --git a/src/mem/slicc/symbols/State.hh b/src/mem/slicc/symbols/State.hh
deleted file mode 100644
index 39900d506..000000000
--- a/src/mem/slicc/symbols/State.hh
+++ /dev/null
@@ -1,45 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- */
-
-#ifndef STATE_H
-#define STATE_H
-
-#include "mem/slicc/symbols/Symbol.hh"
-
-class State : public Symbol {
-public:
- State(string id, const Location& location, const Map<string, string>& pairs) : Symbol(id, location, pairs) {}
- void print(ostream& out) const { out << "[State: " << getIdent() << "]"; }
-};
-
-#endif //STATE_H
diff --git a/src/mem/slicc/symbols/State.py b/src/mem/slicc/symbols/State.py
new file mode 100644
index 000000000..123693256
--- /dev/null
+++ b/src/mem/slicc/symbols/State.py
@@ -0,0 +1,34 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.symbols.Symbol import Symbol
+
+class State(Symbol):
+ def __repr__(self):
+ return "[State: %s]" % self.ident
+
+__all__ = [ "State" ]
diff --git a/src/mem/slicc/symbols/StateMachine.cc b/src/mem/slicc/symbols/StateMachine.cc
deleted file mode 100644
index 86f92b692..000000000
--- a/src/mem/slicc/symbols/StateMachine.cc
+++ /dev/null
@@ -1,1534 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- * */
-
-#include "mem/slicc/symbols/StateMachine.hh"
-#include "mem/slicc/generator/fileio.hh"
-#include "mem/slicc/generator/html_gen.hh"
-#include "mem/slicc/symbols/Action.hh"
-#include "mem/slicc/symbols/Event.hh"
-#include "mem/slicc/symbols/State.hh"
-#include "mem/slicc/symbols/Transition.hh"
-#include "mem/slicc/symbols/Var.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-#include "mem/gems_common/util.hh"
-#include "mem/gems_common/Vector.hh"
-#include "mem/slicc/ast/FormalParamAST.hh"
-
-#include <set>
-
-StateMachine::StateMachine(string ident, const Location& location, const Map<string, string>& pairs, Vector<FormalParamAST*>* config_parameters)
- : Symbol(ident, location, pairs)
-{
- m_table_built = false;
- m_config_parameters = config_parameters;
-
- for (int i=0; i< m_config_parameters->size(); i++) {
- Var* var = new Var(m_config_parameters->ref(i)->getName(),
- location,
- m_config_parameters->ref(i)->getType(),
- "m_"+m_config_parameters->ref(i)->getName(),
- Map<string, string>(),
- this);
- g_sym_table.registerSym(m_config_parameters->ref(i)->getName(), var);
- }
-}
-
-StateMachine::~StateMachine()
-{
- // FIXME
- // assert(0);
-}
-
-void StateMachine::addState(State* state_ptr)
-{
- assert(m_table_built == false);
- m_state_map.add(state_ptr, m_states.size());
- m_states.insertAtBottom(state_ptr);
-}
-
-void StateMachine::addEvent(Event* event_ptr)
-{
- assert(m_table_built == false);
- m_event_map.add(event_ptr, m_events.size());
- m_events.insertAtBottom(event_ptr);
-}
-
-void StateMachine::addAction(Action* action_ptr)
-{
- assert(m_table_built == false);
-
- // Check for duplicate action
- int size = m_actions.size();
- for(int i=0; i<size; i++) {
- if (m_actions[i]->getIdent() == action_ptr->getIdent()) {
- m_actions[i]->warning("Duplicate action definition: " + m_actions[i]->getIdent());
- action_ptr->error("Duplicate action definition: " + action_ptr->getIdent());
- }
- if (m_actions[i]->getShorthand() == action_ptr->getShorthand()) {
- m_actions[i]->warning("Duplicate action shorthand: " + m_actions[i]->getIdent());
- m_actions[i]->warning(" shorthand = " + m_actions[i]->getShorthand());
- action_ptr->warning("Duplicate action shorthand: " + action_ptr->getIdent());
- action_ptr->error(" shorthand = " + action_ptr->getShorthand());
- }
- }
-
- m_actions.insertAtBottom(action_ptr);
-}
-
-void StateMachine::addTransition(Transition* trans_ptr)
-{
- assert(m_table_built == false);
- trans_ptr->checkIdents(m_states, m_events, m_actions);
- m_transitions.insertAtBottom(trans_ptr);
-}
-
-void StateMachine::addFunc(Func* func_ptr)
-{
- // register func in the symbol table
- g_sym_table.registerSym(func_ptr->toString(), func_ptr);
- m_internal_func_vec.insertAtBottom(func_ptr);
-}
-
-void StateMachine::buildTable()
-{
- assert(m_table_built == false);
- int numStates = m_states.size();
- int numEvents = m_events.size();
- int numTransitions = m_transitions.size();
- int stateIndex, eventIndex;
-
- for(stateIndex=0; stateIndex < numStates; stateIndex++) {
- m_table.insertAtBottom(Vector<Transition*>());
- for(eventIndex=0; eventIndex < numEvents; eventIndex++) {
- m_table[stateIndex].insertAtBottom(NULL);
- }
- }
-
- for(int i=0; i<numTransitions; i++) {
- Transition* trans_ptr = m_transitions[i];
-
- // Track which actions we touch so we know if we use them all --
- // really this should be done for all symbols as part of the
- // symbol table, then only trigger it for Actions, States, Events,
- // etc.
-
- Vector<Action*> actions = trans_ptr->getActions();
- for(int actionIndex=0; actionIndex < actions.size(); actionIndex++) {
- actions[actionIndex]->markUsed();
- }
-
- stateIndex = getStateIndex(trans_ptr->getStatePtr());
- eventIndex = getEventIndex(trans_ptr->getEventPtr());
- if (m_table[stateIndex][eventIndex] != NULL) {
- m_table[stateIndex][eventIndex]->warning("Duplicate transition: " + m_table[stateIndex][eventIndex]->toString());
- trans_ptr->error("Duplicate transition: " + trans_ptr->toString());
- }
- m_table[stateIndex][eventIndex] = trans_ptr;
- }
-
- // Look at all actions to make sure we used them all
- for(int actionIndex=0; actionIndex < m_actions.size(); actionIndex++) {
- Action* action_ptr = m_actions[actionIndex];
- if (!action_ptr->wasUsed()) {
- string error_msg = "Unused action: " + action_ptr->getIdent();
- if (action_ptr->existPair("desc")) {
- error_msg += ", " + action_ptr->getDescription();
- }
- action_ptr->warning(error_msg);
- }
- }
-
- m_table_built = true;
-}
-
-const Transition* StateMachine::getTransPtr(int stateIndex, int eventIndex) const
-{
- return m_table[stateIndex][eventIndex];
-}
-
-// *********************** //
-// ******* C Files ******* //
-// *********************** //
-
-void StateMachine::writeCFiles(string path)
-{
- string comp = getIdent();
- string filename;
-
- // Output the method declarations for the class declaration
- {
- ostringstream sstr;
- printControllerH(sstr, comp);
- conditionally_write_file(path + comp + "_Controller.hh", sstr);
- }
-
- // Output switch statement for transition table
- {
- ostringstream sstr;
- printCSwitch(sstr, comp);
- conditionally_write_file(path + comp + "_Transitions.cc", sstr);
- }
-
- // Output the actions for performing the actions
- {
- ostringstream sstr;
- printControllerC(sstr, comp);
- conditionally_write_file(path + comp + "_Controller.cc", sstr);
- }
-
- // Output the wakeup loop for the events
- {
- ostringstream sstr;
- printCWakeup(sstr, comp);
- conditionally_write_file(path + comp + "_Wakeup.cc", sstr);
- }
-
- // Profiling
- {
- ostringstream sstr;
- printProfilerC(sstr, comp);
- conditionally_write_file(path + comp + "_Profiler.cc", sstr);
- }
- {
- ostringstream sstr;
- printProfilerH(sstr, comp);
- conditionally_write_file(path + comp + "_Profiler.hh", sstr);
- }
-
- // Write internal func files
- for(int i=0; i<m_internal_func_vec.size(); i++) {
- m_internal_func_vec[i]->writeCFiles(path);
- }
-
-}
-
-void StateMachine::printControllerH(ostream& out, string component)
-{
-
- m_message_buffer_names.clear();
-
- out << "/** \\file " << getIdent() << ".hh" << endl;
- out << " * " << endl;
- out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << " * Created by slicc definition of Module \"" << getShorthand() << "\"" << endl;
- out << " */" << endl;
- out << endl;
- out << "#ifndef " << component << "_CONTROLLER_H" << endl;
- out << "#define " << component << "_CONTROLLER_H" << endl;
- out << endl;
- out << "#include \"mem/ruby/common/Global.hh\"" << endl;
- out << "#include \"mem/ruby/common/Consumer.hh\"" << endl;
- out << "#include \"mem/ruby/slicc_interface/AbstractController.hh\"" << endl;
- out << "#include \"mem/protocol/TransitionResult.hh\"" << endl;
- out << "#include \"mem/protocol/Types.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_Profiler.hh\"" << endl;
-
- // include object classes
- std::set<string> seen_types;
- for(int i=0; i<numObjects(); i++) {
- Var* var = m_objs[i];
- if (seen_types.count(var->getType()->cIdent()) == 0) {
- out << "#include \"mem/protocol/" << var->getType()->cIdent() << ".hh\"" << endl;
- // out << "class " << var->getType()->cIdent() << ";" << endl;
- seen_types.insert(var->getType()->cIdent());
- }
- }
-
- out << endl;
-
- // for adding information to the protocol debug trace
- out << "extern stringstream " << component << "_" << "transitionComment;" << endl;
-
- out << "class " << component << "_Controller : public AbstractController {" << endl;
-
- /* the coherence checker needs to call isBlockExclusive() and isBlockShared()
- making the Chip a friend class is an easy way to do this for now */
- out << "#ifdef CHECK_COHERENCE" << endl;
- out << "#endif /* CHECK_COHERENCE */" << endl;
-
- out << "public:" << endl;
- // out << " " << component << "_Controller(int version, Network* net_ptr);" << endl;
- out << " " << component << "_Controller(const string & name);" << endl;
- out << " static int getNumControllers();" << endl;
- out << " void init(Network* net_ptr, const vector<string> & argv);" << endl;
- out << " MessageBuffer* getMandatoryQueue() const;" << endl;
- out << " const int & getVersion() const;" << endl;
- out << " const string toString() const;" << endl;
- out << " const string getName() const;" << endl;
- out << " const MachineType getMachineType() const;" << endl;
- out << " void print(ostream& out) const;" << endl;
- out << " void printConfig(ostream& out) const;" << endl;
- out << " void wakeup();" << endl;
- out << " void set_atomic(Address addr);" << endl;
- out << " void started_writes();" << endl;
- out << " void clear_atomic();" << endl;
- out << " void printStats(ostream& out) const { s_profiler.dumpStats(out); }" << endl;
- out << " void clearStats() { s_profiler.clearStats(); }" << endl;
- out << "private:" << endl;
-//added by SS
-// found_to_mem = 0;
- for(int i=0;i<m_config_parameters->size();i++){
- out << " int m_" << m_config_parameters->ref(i)->getName() << ";" << endl;
- }
- if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
- out << " int servicing_atomic;" << endl;
- out << " bool started_receiving_writes;" << endl;
- out << " Address locked_read_request1;" << endl;
- out << " Address locked_read_request2;" << endl;
- out << " Address locked_read_request3;" << endl;
- out << " Address locked_read_request4;" << endl;
- out << " int read_counter;" << endl;
- }
- out << " int m_number_of_TBEs;" << endl;
-
- out << " TransitionResult doTransition(" << component << "_Event event, " << component
- << "_State state, const Address& addr";
- if(CHECK_INVALID_RESOURCE_STALLS) {
- out << ", int priority";
- }
- out << "); // in " << component << "_Transitions.cc" << endl;
- out << " TransitionResult doTransitionWorker(" << component << "_Event event, " << component
- << "_State state, " << component << "_State& next_state, const Address& addr";
- if(CHECK_INVALID_RESOURCE_STALLS) {
- out << ", int priority";
- }
- out << "); // in " << component << "_Transitions.cc" << endl;
- out << " string m_name;" << endl;
- out << " int m_transitions_per_cycle;" << endl;
- out << " int m_buffer_size;" << endl;
- out << " int m_recycle_latency;" << endl;
- out << " map< string, string > m_cfg;" << endl;
- out << " NodeID m_version;" << endl;
- out << " Network* m_net_ptr;" << endl;
- out << " MachineID m_machineID;" << endl;
- out << " " << component << "_Profiler s_profiler;" << endl;
- out << " static int m_num_controllers;" << endl;
-
- // internal function protypes
- out << " // Internal functions" << endl;
- for(int i=0; i<m_internal_func_vec.size(); i++) {
- Func* func = m_internal_func_vec[i];
- string proto;
- func->funcPrototype(proto);
- if (proto != "") {
- out << " " << proto;
- }
- }
-
- out << " // Actions" << endl;
- for(int i=0; i < numActions(); i++) {
- const Action& action = getAction(i);
- out << "/** \\brief " << action.getDescription() << "*/" << endl;
- out << " void " << action.getIdent() << "(const Address& addr);" << endl;
- }
-
- // the controller internal variables
- out << " // Object" << endl;
- for(int i=0; i < numObjects(); i++) {
- const Var* var = m_objs[i];
- string template_hack = "";
- if (var->existPair("template_hack")) {
- template_hack = var->lookupPair("template_hack");
- }
- out << " " << var->getType()->cIdent() << template_hack << "* m_"
- << var->cIdent() << "_ptr;" << endl;
-
- string str = "m_"+ var->cIdent() + "_ptr";
- if (var->getType()->cIdent() == "MessageBuffer")
- m_message_buffer_names.push_back(str);
-
- }
-
-
- out << "};" << endl;
- out << "#endif // " << component << "_CONTROLLER_H" << endl;
-}
-
-void StateMachine::printControllerC(ostream& out, string component)
-{
- out << "/** \\file " << getIdent() << ".cc" << endl;
- out << " * " << endl;
- out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << " * Created by slicc definition of Module \"" << getShorthand() << "\"" << endl;
- out << " */" << endl;
- out << endl;
- out << "#include \"mem/ruby/common/Global.hh\"" << endl;
- out << "#include \"mem/ruby/slicc_interface/RubySlicc_includes.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_Controller.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_State.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl;
- out << "#include \"mem/protocol/Types.hh\"" << endl;
- out << "#include \"mem/ruby/system/System.hh\"" << endl;
-
- // include object classes
- std::set<string> seen_types;
- for(int i=0; i<numObjects(); i++) {
- Var* var = m_objs[i];
- if (seen_types.count(var->getType()->cIdent()) == 0) {
- out << "#include \"mem/protocol/" << var->getType()->cIdent() << ".hh\"" << endl;
- seen_types.insert(var->getType()->cIdent());
- }
-
- }
-
- out << endl;
-
- out << "int " << component << "_Controller::m_num_controllers = 0;" << endl;
-
- // for adding information to the protocol debug trace
- out << "stringstream " << component << "_" << "transitionComment;" << endl;
- out << "#define APPEND_TRANSITION_COMMENT(str) (" << component << "_" << "transitionComment << str)" << endl;
-
- out << "/** \\brief constructor */" << endl;
- out << component << "_Controller::" << component
- // << "_Controller(int version, Network* net_ptr)" << endl;
- << "_Controller(const string & name)" << endl;
- out << " : m_name(name)" << endl;
- out << "{ " << endl;
- if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
- out << " servicing_atomic = 0;" << endl;
- out << " started_receiving_writes = false;" << endl;
- out << " locked_read_request1 = Address(-1);" << endl;
- out << " locked_read_request2 = Address(-1);" << endl;
- out << " locked_read_request3 = Address(-1);" << endl;
- out << " locked_read_request4 = Address(-1);" << endl;
- out << " read_counter = 0;" << endl;
- }
- out << " m_num_controllers++; " << endl;
- for(int i=0; i < numObjects(); i++) {
- const Var* var = m_objs[i];
- if ( var->cIdent().find("mandatoryQueue") != string::npos)
- out << " m_" << var->cIdent() << "_ptr = new " << var->getType()->cIdent() << "();" << endl;
- }
- out << "}" << endl << endl;
-
- out << "void " << component << "_Controller::init(Network * net_ptr, const vector<string> & argv)" << endl;
- out << "{" << endl;
- out << " for (size_t i=0; i < argv.size(); i+=2) {" << endl;
-// out << " printf (\"ARG: %s = %s \\n \", argv[i].c_str(), argv[i+1].c_str());"<< endl;
-
- out << " if (argv[i] == \"version\") " << endl;
- out << " m_version = atoi(argv[i+1].c_str());" << endl;
- out << " else if (argv[i] == \"transitions_per_cycle\") " << endl;
- out << " m_transitions_per_cycle = atoi(argv[i+1].c_str());" << endl;
- out << " else if (argv[i] == \"buffer_size\") " << endl;
- out << " m_buffer_size = atoi(argv[i+1].c_str());" << endl;
-//added by SS
- out << " else if (argv[i] == \"recycle_latency\") " << endl;
- out << " m_recycle_latency = atoi(argv[i+1].c_str());" << endl;
-//added by SS --> for latency
-//for loop on latency_vector to check with argv[i] and assign the value to the related m_latency ...
- out << " else if (argv[i] == \"number_of_TBEs\") " << endl;
- out << " m_number_of_TBEs = atoi(argv[i+1].c_str());" << endl;
-
- if (m_config_parameters->size()) {
- for(int i= 0 ; i < m_config_parameters->size(); i++) {
- out << " else if (argv[i] == \"" << m_config_parameters->ref(i)->getName() << "\")" << endl;
- if (m_config_parameters->ref(i)->getTypeName() == "int")
- out << " m_" << m_config_parameters->ref(i)->getName() << "=" << "atoi(argv[i+1].c_str());" << endl;
- else
- assert(0); // only int parameters are supported right now
- // if (str == "to_mem_ctrl_latency")
- // out << " m_" << (*it)->c_str() << "=" << "atoi(argv[i+1].c_str())+(random() % 5);" << endl;
- }
- }
- out << " }" << endl;
- out << " m_net_ptr = net_ptr;" << endl;
- out << " m_machineID.type = MachineType_" << component << ";" << endl;
- out << " m_machineID.num = m_version;" << endl;
-
- // make configuration array
- out << " for (size_t i=0; i < argv.size(); i+=2) {" << endl;
- out << " if (argv[i] != \"version\") " << endl;
- out << " m_cfg[argv[i]] = argv[i+1];" << endl;
- out << " }" << endl;
-
- out << endl;
-
- // initialize objects
- out << " // Objects" << endl;
- out << " s_profiler.setVersion(m_version);" << endl;
- for(int i=0; i < numObjects(); i++) {
- const Var* var = m_objs[i];
- if (!var->existPair("network")) {
- // Not a network port object
- if (var->getType()->existPair("primitive")) {
- out << " m_" << var->cIdent() << "_ptr = new " << var->getType()->cIdent() << ";\n";
- if (var->existPair("default")) {
- out << " (*m_" << var->cIdent() << "_ptr) = " << var->lookupPair("default") << ";\n";
- }
- out << " }\n";
-
- } else {
- // Normal Object
- string template_hack = "";
- if (var->existPair("template_hack")) {
- template_hack = var->lookupPair("template_hack");
- }
-//added by SS
- string str = "";
- int found = 0;
- if (var->existPair("factory")) {
- out << " m_" << var->cIdent() << "_ptr = " << var->lookupPair("factory");
- } else {
- if ( var->cIdent().find("mandatoryQueue") == string::npos) {
-
- str = " m_" + var->cIdent() + "_ptr = new " + var->getType()->cIdent() + template_hack;
- out << str;
- if (str.find("TBETable")!=string::npos){
- found = 1;
- }
-
- if (!var->getType()->existPair("non_obj") && (!var->getType()->isEnumeration())) {
- str = "";
- if (var->existPair("constructor_hack")) {
- string constructor_hack = var->lookupPair("constructor_hack");
- str = "(" + constructor_hack + ")";
- } else {
- str = "()";
- }
- if (found)
- str = "(m_number_of_TBEs)";
- out << str;
- }
- }
- }
-
- out << ";\n";
- out << " assert(m_" << var->cIdent() << "_ptr != NULL);" << endl;
-
- if (var->existPair("default")) {
- out << " (*m_" << var->cIdent() << "_ptr) = " << var->lookupPair("default")
- << "; // Object default" << endl;
- } else if (var->getType()->hasDefault()) {
- out << " (*m_" << var->cIdent() << "_ptr) = " << var->getType()->getDefault()
- << "; // Type " << var->getType()->getIdent() << " default" << endl;
- }
-
- // Set ordering
- if (var->existPair("ordered") && !var->existPair("trigger_queue")) {
- // A buffer
- string ordered = var->lookupPair("ordered");
- out << " m_" << var->cIdent() << "_ptr->setOrdering(" << ordered << ");\n";
- }
-
- // Set randomization
- if (var->existPair("random")) {
- // A buffer
- string value = var->lookupPair("random");
- out << " m_" << var->cIdent() << "_ptr->setRandomization(" << value << ");\n";
- }
-
- // Set Priority
- if (var->getType()->isBuffer() && var->existPair("rank") && !var->existPair("trigger_queue")) {
- string rank = var->lookupPair("rank");
- out << " m_" << var->cIdent() << "_ptr->setPriority(" << rank << ");\n";
- }
- }
- } else {
- // Network port object
- string network = var->lookupPair("network");
- string ordered = var->lookupPair("ordered");
- string vnet = var->lookupPair("virtual_network");
-
- assert (var->getMachine() != NULL);
- out << " m_" << var->cIdent() << "_ptr = m_net_ptr->get"
- << network << "NetQueue(m_version+MachineType_base_number(string_to_MachineType(\""
- << var->getMachine()->getIdent() << "\")), "
- << ordered << ", " << vnet << ");\n";
- out << " assert(m_" << var->cIdent() << "_ptr != NULL);" << endl;
-
- // Set ordering
- if (var->existPair("ordered")) {
- // A buffer
- string ordered = var->lookupPair("ordered");
- out << " m_" << var->cIdent() << "_ptr->setOrdering(" << ordered << ");\n";
- }
-
- // Set randomization
- if (var->existPair("random")) {
- // A buffer
- string value = var->lookupPair("random");
- out << " m_" << var->cIdent() << "_ptr->setRandomization(" << value << ");\n";
- }
-
- // Set Priority
- if (var->existPair("rank")) {
- string rank = var->lookupPair("rank");
- out << " m_" << var->cIdent() << "_ptr->setPriority(" << rank << ");\n";
- }
-
- // Set buffer size
- if (var->getType()->isBuffer()) {
- out << " if (m_buffer_size > 0) {\n";
- out << " m_" << var->cIdent() << "_ptr->setSize(m_buffer_size);\n";
- out << " }\n";
- }
-
- // set description (may be overriden later by port def)
- out << " m_" << var->cIdent()
- << "_ptr->setDescription(\"[Version \" + int_to_string(m_version) + \", "
- << component << ", name=" << var->cIdent() << "]\");" << endl;
- out << endl;
- }
- }
-
- // Set the queue consumers
- out << endl;
- for(int i=0; i < m_in_ports.size(); i++) {
- const Var* port = m_in_ports[i];
- out << " " << port->getCode() << ".setConsumer(this);" << endl;
- }
-
- // Set the queue descriptions
- out << endl;
- for(int i=0; i < m_in_ports.size(); i++) {
- const Var* port = m_in_ports[i];
- out << " " << port->getCode()
- << ".setDescription(\"[Version \" + int_to_string(m_version) + \", "
- << component << ", " << port->toString() << "]\");" << endl;
- }
-
- // Initialize the transition profiling
- out << endl;
- for(int i=0; i<numTransitions(); i++) {
- const Transition& t = getTransition(i);
- const Vector<Action*>& action_vec = t.getActions();
- int numActions = action_vec.size();
-
- // Figure out if we stall
- bool stall = false;
- for (int i=0; i<numActions; i++) {
- if(action_vec[i]->getIdent() == "z_stall") {
- stall = true;
- }
- }
-
- // Only possible if it is not a 'z' case
- if (!stall) {
- out << " s_profiler.possibleTransition(" << component << "_State_"
- << t.getStatePtr()->getIdent() << ", " << component << "_Event_"
- << t.getEventPtr()->getIdent() << ");" << endl;
- }
- }
-
- //added by SS to initialize recycle_latency of message buffers
- std::vector<std::string>::const_iterator it;
- for ( it=m_message_buffer_names.begin() ; it != m_message_buffer_names.end(); it++ ){
- out << " "<< (*it).c_str() << "->setRecycleLatency(m_recycle_latency);" << endl;
- }
-
-
- out << "}" << endl;
-
- out << endl;
-
- bool has_mandatory_q = false;
- for(int i=0; i < m_in_ports.size(); i++) {
- if (m_in_ports[i]->getCode().find("mandatoryQueue_ptr")!= string::npos)
- has_mandatory_q = true;
- }
-
- out << "int " << component << "_Controller::getNumControllers() {" << endl;
- out << " return m_num_controllers;" << endl;
- out << "}" << endl;
-
- out << endl;
-
- out << "MessageBuffer* " << component << "_Controller::getMandatoryQueue() const {" << endl;
- if (has_mandatory_q)
- out << " return m_" << component << "_mandatoryQueue_ptr;" << endl;
- else
- out << " return NULL;" << endl;
- out << "}" << endl;
-
- out << endl;
-
- out << "const int & "<<component<<"_Controller::getVersion() const{" << endl;
- out << " return m_version;" << endl;
- out << "}";
-
- out << endl;
-
- out << "const string "<<component<<"_Controller::toString() const{" << endl;
- out << " return \"" << component<< "_Controller\";" << endl;
- out << "}";
-
- out << endl;
-
- out << "const string "<<component<<"_Controller::getName() const{" << endl;
- out << " return m_name;" << endl;
- out << "}";
-
- out << endl;
-
- out << "const MachineType "<<component<<"_Controller::getMachineType() const{" << endl;
- out << " return MachineType_" << component<< ";" << endl;
- out << "}";
-
- out << endl;
-
- out << "void " << component << "_Controller::print(ostream& out) const { out << \"[" << component
- << "_Controller \" << m_version << \"]\"; }" << endl;
-
- out << "void " << component << "_Controller::printConfig(ostream& out) const {" << endl;
- out << " out << \"" << component << "_Controller config: \" << m_name << endl;" << endl;
- out << " out << \" version: \" << m_version << endl;" << endl;
- out << " for(map< string, string >::const_iterator it = m_cfg.begin(); it != m_cfg.end(); it++) {" << endl;
- out << " out << \" \" << (*it).first << \": \" << (*it).second << endl;" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
- out << endl;
- out << "// Actions" << endl;
- out << endl;
-
- for(int i=0; i < numActions(); i++) {
- const Action& action = getAction(i);
- if (action.existPair("c_code")) {
- out << "/** \\brief " << action.getDescription() << "*/" << endl;
- out << "void " << component << "_Controller::"
- << action.getIdent() << "(const Address& addr)" << endl;
- out << "{" << endl;
- out << " DEBUG_MSG(GENERATED_COMP, HighPrio,\"executing\");" << endl;
-//added by SS
-//it should point to m_latency...
-//so I should change the string output of this lookup
-
-
- string c_code_string = action.lookupPair("c_code");
-
- out << c_code_string;
-
- out << "}" << endl;
- }
- out << endl;
- }
-}
-
-void StateMachine::printCWakeup(ostream& out, string component)
-{
- out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << "// " << getIdent() << ": " << getShorthand() << endl;
- out << endl;
- out << "#include \"mem/ruby/common/Global.hh\"" << endl;
- out << "#include \"mem/ruby/slicc_interface/RubySlicc_includes.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_Controller.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_State.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl;
- out << "#include \"mem/protocol/Types.hh\"" << endl;
- out << "#include \"mem/ruby/system/System.hh\"" << endl;
- out << endl;
- out << "void " << component << "_Controller::wakeup()" << endl;
- out << "{" << endl;
- // out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,*this);" << endl;
- // out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,g_eventQueue_ptr->getTime());" << endl;
- out << endl;
- out << "int counter = 0;" << endl;
- out << " while (true) {" << endl;
- out << " // Some cases will put us into an infinite loop without this limit" << endl;
- out << " assert(counter <= m_transitions_per_cycle);" << endl;
- out << " if (counter == m_transitions_per_cycle) {" << endl;
- out << " g_system_ptr->getProfiler()->controllerBusy(m_machineID); // Count how often we're fully utilized" << endl;
- out << " g_eventQueue_ptr->scheduleEvent(this, 1); // Wakeup in another cycle and try again" << endl;
- out << " break;" << endl;
- out << " }" << endl;
-
- // InPorts
- //
- // Find the position of the mandatory queue in the vector so that we can print it out first
- int j = -1;
- if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
- for(int i=0; i < m_in_ports.size(); i++) {
- const Var* port = m_in_ports[i];
- assert(port->existPair("c_code_in_port"));
- if (port->toString().find("mandatoryQueue_in") != string::npos) {
- assert (j == -1);
- j = i;
- }
- else {
- cout << port->toString() << endl << flush;
- }
- }
-
- assert(j != -1);
-
- // print out the mandatory queue here
- const Var* port = m_in_ports[j];
- assert(port->existPair("c_code_in_port"));
- out << " // "
- << component << "InPort " << port->toString()
- << endl;
- string output = port->lookupPair("c_code_in_port");
- string::size_type pos = output.find("TransitionResult result = doTransition((L1Cache_mandatory_request_type_to_event(((*in_msg_ptr)).m_Type)), L1Cache_getState(addr), addr);");
- assert(pos != string::npos);
- string atomics_string = "\n \
- if ((((*in_msg_ptr)).m_Type) == CacheRequestType_ATOMIC) { \n \
- if (servicing_atomic == 0) { \n \
- if (locked_read_request1 == Address(-1)) { \n \
- assert(read_counter == 0); \n \
- locked_read_request1 = addr; \n \
- assert(read_counter == 0); \n \
- read_counter++; \n \
- } \n \
- else if (addr == locked_read_request1) { \n \
- ; // do nothing \n\
- } \n \
- else { \n \
- assert(0); // should never be here if servicing one request at a time \n\
- } \n \
- } \n \
- else if (!started_receiving_writes) { \n \
- if (servicing_atomic == 1) { \n \
- if (locked_read_request2 == Address(-1)) { \n \
- assert(locked_read_request1 != Address(-1)); \n \
- assert(read_counter == 1); \n \
- locked_read_request2 = addr; \n \
- assert(read_counter == 1); \n \
- read_counter++; \n \
- } \n \
- else if (addr == locked_read_request2) { \n \
- ; // do nothing \n\
- } \n \
- else { \n \
- assert(0); // should never be here if servicing one request at a time \n\
- } \n \
- } \n \
- else if (servicing_atomic == 2) { \n \
- if (locked_read_request3 == Address(-1)) { \n \
- assert(locked_read_request1 != Address(-1)); \n \
- assert(locked_read_request2 != Address(-1)); \n \
- assert(read_counter == 1); \n \
- locked_read_request3 = addr; \n \
- assert(read_counter == 2); \n \
- read_counter++; \n \
- } \n \
- else if (addr == locked_read_request3) { \n \
- ; // do nothing \n\
- } \n \
- else { \n \
- assert(0); // should never be here if servicing one request at a time \n\
- } \n \
- } \n \
- else if (servicing_atomic == 3) { \n \
- if (locked_read_request4 == Address(-1)) { \n \
- assert(locked_read_request1 != Address(-1)); \n \
- assert(locked_read_request2 != Address(-1)); \n \
- assert(locked_read_request3 != Address(-1)); \n \
- assert(read_counter == 1); \n \
- locked_read_request4 = addr; \n \
- assert(read_counter == 3); \n \
- read_counter++; \n \
- } \n \
- else if (addr == locked_read_request4) { \n \
- ; // do nothing \n\
- } \n \
- else { \n \
- assert(0); // should never be here if servicing one request at a time \n\
- } \n \
- } \n \
- else { \n \
- assert(0); \n \
- } \n \
- } \n \
- } \n \
- else { \n \
- if (servicing_atomic > 0) { \n \
- // reset \n \
- servicing_atomic = 0; \n \
- read_counter = 0; \n \
- started_receiving_writes = false; \n \
- locked_read_request1 = Address(-1); \n \
- locked_read_request2 = Address(-1); \n \
- locked_read_request3 = Address(-1); \n \
- locked_read_request4 = Address(-1); \n \
- } \n \
- } \n \
- ";
- output.insert(pos, atomics_string);
- /*string foo = "// Cannot do anything with this transition, go check next doable transition (mostly likely of next port)\n";
- string::size_type next_pos = output.find(foo, pos);
- next_pos = next_pos + foo.length();
-
- assert(next_pos != string::npos);
- string complete = " }\n";
- output.insert(next_pos, complete);*/
- //out << port->lookupPair("c_code_in_port");
- out << output;
- out << endl;
- }
- for(int i=0; i < m_in_ports.size(); i++) {
- const Var* port = m_in_ports[i];
- // don't print out mandatory queue twice
- if (i != j) {
- if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
- if (port->toString().find("forwardRequestNetwork_in") != string::npos) {
- out << " bool postpone = false;" << endl;
- out << " if ((((*m_L1Cache_forwardToCache_ptr)).isReady())) {" << endl;
- out << " const RequestMsg* in_msg_ptr;" << endl;
- out << " in_msg_ptr = dynamic_cast<const RequestMsg*>(((*m_L1Cache_forwardToCache_ptr)).peek());" << endl;
- out << " if ((((servicing_atomic == 1) && (locked_read_request1 == ((*in_msg_ptr)).m_Address)) || " << endl;
- out << " ((servicing_atomic == 2) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address)) || " << endl;
- out << " ((servicing_atomic == 3) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address || locked_read_request3 == ((*in_msg_ptr)).m_Address)) || " << endl;
- out << " ((servicing_atomic == 4) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address || locked_read_request3 == ((*in_msg_ptr)).m_Address || locked_read_request1 == ((*in_msg_ptr)).m_Address)))) {" << endl;
-// out << " (locked_read_request2 == ((*in_msg_ptr)).m_Address) || (locked_read_request3 == ((*in_msg_ptr)).m_Address) || " << endl;
-// out << " (locked_read_request4 == ((*in_msg_ptr)).m_Address))) { " << endl;
-
- out << " postpone = true;" << endl;
- out << " }" << endl;
-
- out << " }" << endl;
- out << " if (!postpone) {" << endl;
- }
- }
- assert(port->existPair("c_code_in_port"));
- out << " // "
- << component << "InPort " << port->toString()
- << endl;
- out << port->lookupPair("c_code_in_port");
- if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
- if (port->toString().find("forwardRequestNetwork_in") != string::npos) {
- out << "}" << endl;
- }
- }
- out << endl;
- }
- }
-
- out << " break; // If we got this far, we have nothing left todo" << endl;
- out << " }" << endl;
- // out << " g_eventQueue_ptr->scheduleEvent(this, 1);" << endl;
- // out << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl;
- out << "}" << endl;
- out << endl;
-
-
- // tack on two more functions
- if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
- out << "void " << component << "_Controller::set_atomic(Address addr)" << endl;
- out << "{" << endl;
- out << " servicing_atomic++; " << endl;
- out << "}" << endl;
- out << "void " << component << "_Controller::started_writes()" << endl;
- out << "{" << endl;
- out << " started_receiving_writes = true; " << endl;
- out << "}" << endl;
- out << "void " << component << "_Controller::clear_atomic()" << endl;
- out << "{" << endl;
- out << " assert(servicing_atomic > 0); " << endl;
- out << " read_counter--; " << endl;
- out << " servicing_atomic--; " << endl;
- out << " if (read_counter == 0) { " << endl;
- out << " servicing_atomic = 0; " << endl;
- out << " started_receiving_writes = false; " << endl;
- out << " locked_read_request1 = Address(-1); " << endl;
- out << " locked_read_request2 = Address(-1); " << endl;
- out << " locked_read_request3 = Address(-1); " << endl;
- out << " locked_read_request4 = Address(-1); " << endl;
- out << " } " << endl;
- out << "}" << endl;
- }
- else {
- out << "void " << component << "_Controller::started_writes()" << endl;
- out << "{" << endl;
- out << " assert(0); " << endl;
- out << "}" << endl;
- out << "void " << component << "_Controller::set_atomic(Address addr)" << endl;
- out << "{" << endl;
- out << " assert(0); " << endl;
- out << "}" << endl;
-
- out << "void " << component << "_Controller::clear_atomic()" << endl;
- out << "{" << endl;
- out << " assert(0); " << endl;
- out << "}" << endl;
- }
-
-}
-
-void StateMachine::printCSwitch(ostream& out, string component)
-{
- out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << "// " << getIdent() << ": " << getShorthand() << endl;
- out << endl;
- out << "#include \"mem/ruby/common/Global.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_Controller.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_State.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl;
- out << "#include \"mem/protocol/Types.hh\"" << endl;
- out << "#include \"mem/ruby/system/System.hh\"" << endl;
- out << endl;
- out << "#define HASH_FUN(state, event) ((int(state)*" << component
- << "_Event_NUM)+int(event))" << endl;
- out << endl;
- out << "#define GET_TRANSITION_COMMENT() (" << component << "_" << "transitionComment.str())" << endl;
- out << "#define CLEAR_TRANSITION_COMMENT() (" << component << "_" << "transitionComment.str(\"\"))" << endl;
- out << endl;
- out << "TransitionResult " << component << "_Controller::doTransition("
- << component << "_Event event, "
- << component << "_State state, "
- << "const Address& addr" << endl;
- if(CHECK_INVALID_RESOURCE_STALLS) {
- out << ", int priority";
- }
- out << ")" << endl;
-
- out << "{" << endl;
- out << " " << component << "_State next_state = state;" << endl;
- out << endl;
- out << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl;
- out << " DEBUG_MSG(GENERATED_COMP, MedPrio,*this);" << endl;
- out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,g_eventQueue_ptr->getTime());" << endl;
- out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,state);" << endl;
- out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,event);" << endl;
- out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,addr);" << endl;
- out << endl;
- out << " TransitionResult result = doTransitionWorker(event, state, next_state, addr";
- if(CHECK_INVALID_RESOURCE_STALLS) {
- out << ", priority";
- }
- out << ");" << endl;
- out << endl;
- out << " if (result == TransitionResult_Valid) {" << endl;
- out << " DEBUG_EXPR(GENERATED_COMP, MedPrio, next_state);" << endl;
- out << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl;
- out << " s_profiler.countTransition(state, event);" << endl;
- out << " if (Debug::getProtocolTrace()) {" << endl
- << " g_system_ptr->getProfiler()->profileTransition(\"" << component
- << "\", m_version, addr, " << endl
- << " " << component << "_State_to_string(state), " << endl
- << " " << component << "_Event_to_string(event), " << endl
- << " " << component << "_State_to_string(next_state), GET_TRANSITION_COMMENT());" << endl
- << " }" << endl;
- out << " CLEAR_TRANSITION_COMMENT();" << endl;
- out << " " << component << "_setState(addr, next_state);" << endl;
- out << " " << endl;
- out << " } else if (result == TransitionResult_ResourceStall) {" << endl;
- out << " if (Debug::getProtocolTrace()) {" << endl
- << " g_system_ptr->getProfiler()->profileTransition(\"" << component
- << "\", m_version, addr, " << endl
- << " " << component << "_State_to_string(state), " << endl
- << " " << component << "_Event_to_string(event), " << endl
- << " " << component << "_State_to_string(next_state), " << endl
- << " \"Resource Stall\");" << endl
- << " }" << endl;
- out << " } else if (result == TransitionResult_ProtocolStall) {" << endl;
- out << " DEBUG_MSG(GENERATED_COMP,HighPrio,\"stalling\");" << endl
- << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl;
- out << " if (Debug::getProtocolTrace()) {" << endl
- << " g_system_ptr->getProfiler()->profileTransition(\"" << component
- << "\", m_version, addr, " << endl
- << " " << component << "_State_to_string(state), " << endl
- << " " << component << "_Event_to_string(event), " << endl
- << " " << component << "_State_to_string(next_state), " << endl
- << " \"Protocol Stall\");" << endl
- << " }" << endl
- << " }" << endl;
- out << " return result;" << endl;
- out << "}" << endl;
- out << endl;
- out << "TransitionResult " << component << "_Controller::doTransitionWorker("
- << component << "_Event event, "
- << component << "_State state, "
- << component << "_State& next_state, "
- << "const Address& addr" << endl;
- if(CHECK_INVALID_RESOURCE_STALLS) {
- out << ", int priority" << endl;
- }
- out << ")" << endl;
-
- out << "{" << endl;
- out << "" << endl;
-
- out << " switch(HASH_FUN(state, event)) {" << endl;
-
- Map<string, Vector<string> > code_map; // This map will allow suppress generating duplicate code
- Vector<string> code_vec;
-
- for(int i=0; i<numTransitions(); i++) {
- const Transition& t = getTransition(i);
- string case_string = component + "_State_" + t.getStatePtr()->getIdent()
- + ", " + component + "_Event_" + t.getEventPtr()->getIdent();
-
- string code;
-
- code += " {\n";
- // Only set next_state if it changes
- if (t.getStatePtr() != t.getNextStatePtr()) {
- code += " next_state = " + component + "_State_" + t.getNextStatePtr()->getIdent() + ";\n";
- }
-
- const Vector<Action*>& action_vec = t.getActions();
- int numActions = action_vec.size();
-
- // Check for resources
- Vector<string> code_sorter;
- const Map<Var*, string>& res = t.getResources();
- Vector<Var*> res_keys = res.keys();
- for (int i=0; i<res_keys.size(); i++) {
- string temp_code;
- if (res_keys[i]->getType()->cIdent() == "DNUCAStopTable") {
- temp_code += res.lookup(res_keys[i]);
- } else {
- temp_code += " if (!" + (res_keys[i]->getCode()) + ".areNSlotsAvailable(" + res.lookup(res_keys[i]) + ")) {\n";
- if(CHECK_INVALID_RESOURCE_STALLS) {
- // assert that the resource stall is for a resource of equal or greater priority
- temp_code += " assert(priority >= "+ (res_keys[i]->getCode()) + ".getPriority());\n";
- }
- temp_code += " return TransitionResult_ResourceStall;\n";
- temp_code += " }\n";
- }
- code_sorter.insertAtBottom(temp_code);
- }
-
- // Emit the code sequences in a sorted order. This makes the
- // output deterministic (without this the output order can vary
- // since Map's keys() on a vector of pointers is not deterministic
- code_sorter.sortVector();
- for (int i=0; i<code_sorter.size(); i++) {
- code += code_sorter[i];
- }
-
- // Figure out if we stall
- bool stall = false;
- for (int i=0; i<numActions; i++) {
- if(action_vec[i]->getIdent() == "z_stall") {
- stall = true;
- }
- }
-
- if (stall) {
- code += " return TransitionResult_ProtocolStall;\n";
- } else {
- for (int i=0; i<numActions; i++) {
- code += " " + action_vec[i]->getIdent() + "(addr);\n";
- }
- code += " return TransitionResult_Valid;\n";
- }
- code += " }\n";
-
-
- // Look to see if this transition code is unique.
- if (code_map.exist(code)) {
- code_map.lookup(code).insertAtBottom(case_string);
- } else {
- Vector<string> vec;
- vec.insertAtBottom(case_string);
- code_map.add(code, vec);
- code_vec.insertAtBottom(code);
- }
- }
-
- // Walk through all of the unique code blocks and spit out the
- // corresponding case statement elements
- for (int i=0; i<code_vec.size(); i++) {
- string code = code_vec[i];
-
- // Iterative over all the multiple transitions that share the same code
- for (int case_num=0; case_num<code_map.lookup(code).size(); case_num++) {
- string case_string = code_map.lookup(code)[case_num];
- out << " case HASH_FUN(" << case_string << "):" << endl;
- }
- out << code;
- }
-
- out << " default:" << endl;
- out << " WARN_EXPR(m_version);" << endl;
- out << " WARN_EXPR(g_eventQueue_ptr->getTime());" << endl;
- out << " WARN_EXPR(addr);" << endl;
- out << " WARN_EXPR(event);" << endl;
- out << " WARN_EXPR(state);" << endl;
- out << " ERROR_MSG(\"Invalid transition\");" << endl;
- out << " }" << endl;
- out << " return TransitionResult_Valid;" << endl;
- out << "}" << endl;
-}
-
-void StateMachine::printProfilerH(ostream& out, string component)
-{
- out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << "// " << getIdent() << ": " << getShorthand() << endl;
- out << endl;
- out << "#ifndef " << component << "_PROFILER_H" << endl;
- out << "#define " << component << "_PROFILER_H" << endl;
- out << endl;
- out << "#include \"mem/ruby/common/Global.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_State.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl;
- out << endl;
- out << "class " << component << "_Profiler {" << endl;
- out << "public:" << endl;
- out << " " << component << "_Profiler();" << endl;
- out << " void setVersion(int version);" << endl;
- out << " void countTransition(" << component << "_State state, " << component << "_Event event);" << endl;
- out << " void possibleTransition(" << component << "_State state, " << component << "_Event event);" << endl;
- out << " void dumpStats(ostream& out) const;" << endl;
- out << " void clearStats();" << endl;
- out << "private:" << endl;
- out << " int m_counters[" << component << "_State_NUM][" << component << "_Event_NUM];" << endl;
- out << " int m_event_counters[" << component << "_Event_NUM];" << endl;
- out << " bool m_possible[" << component << "_State_NUM][" << component << "_Event_NUM];" << endl;
- out << " int m_version;" << endl;
- out << "};" << endl;
- out << "#endif // " << component << "_PROFILER_H" << endl;
-}
-
-void StateMachine::printProfilerC(ostream& out, string component)
-{
- out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << "// " << getIdent() << ": " << getShorthand() << endl;
- out << endl;
- out << "#include \"mem/protocol/" << component << "_Profiler.hh\"" << endl;
- out << endl;
-
- // Constructor
- out << component << "_Profiler::" << component << "_Profiler()" << endl;
- out << "{" << endl;
- out << " for (int state = 0; state < " << component << "_State_NUM; state++) {" << endl;
- out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl;
- out << " m_possible[state][event] = false;" << endl;
- out << " m_counters[state][event] = 0;" << endl;
- out << " }" << endl;
- out << " }" << endl;
- out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl;
- out << " m_event_counters[event] = 0;" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
- // setVersion
- out << "void " << component << "_Profiler::setVersion(int version)" << endl;
- out << "{" << endl;
- out << " m_version = version;" << endl;
- out << "}" << endl;
-
- // Clearstats
- out << "void " << component << "_Profiler::clearStats()" << endl;
- out << "{" << endl;
- out << " for (int state = 0; state < " << component << "_State_NUM; state++) {" << endl;
- out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl;
- out << " m_counters[state][event] = 0;" << endl;
- out << " }" << endl;
- out << " }" << endl;
- out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl;
- out << " m_event_counters[event] = 0;" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
- // Count Transition
- out << "void " << component << "_Profiler::countTransition(" << component << "_State state, " << component << "_Event event)" << endl;
- out << "{" << endl;
- out << " assert(m_possible[state][event]);" << endl;
- out << " m_counters[state][event]++;" << endl;
- out << " m_event_counters[event]++;" << endl;
- out << "}" << endl;
-
- // Possible Transition
- out << "void " << component << "_Profiler::possibleTransition(" << component << "_State state, " << component << "_Event event)" << endl;
- out << "{" << endl;
- out << " m_possible[state][event] = true;" << endl;
- out << "}" << endl;
-
- // dumpStats
- out << "void " << component << "_Profiler::dumpStats(ostream& out) const" << endl;
- out << "{" << endl;
- out << " out << \" --- " << component << " \" << m_version << \" ---\" << endl;" << endl;
- out << " out << \" - Event Counts -\" << endl;" << endl;
- out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl;
- out << " int count = m_event_counters[event];" << endl;
- out << " out << (" << component << "_Event) event << \" \" << count << endl;" << endl;
- out << " }" << endl;
- out << " out << endl;" << endl;
- out << " out << \" - Transitions -\" << endl;" << endl;
- out << " for (int state = 0; state < " << component << "_State_NUM; state++) {" << endl;
- out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl;
- out << " if (m_possible[state][event]) {" << endl;
- out << " int count = m_counters[state][event];" << endl;
- out << " out << (" << component << "_State) state << \" \" << (" << component << "_Event) event << \" \" << count;" << endl;
- out << " if (count == 0) {" << endl;
- out << " out << \" <-- \";" << endl;
- out << " }" << endl;
- out << " out << endl;" << endl;
- out << " }" << endl;
- out << " }" << endl;
- out << " out << endl;" << endl;
- out << " }" << endl;
- out << "}" << endl;
-}
-
-
-
-// ************************** //
-// ******* HTML Files ******* //
-// ************************** //
-
-string frameRef(string click_href, string click_target, string over_href, string over_target_num, string text)
-{
- string temp;
- temp += "<A href=\"" + click_href + "\" ";
- temp += "target=\"" + click_target + "\" ";
- string javascript = "if (parent.frames[" + over_target_num + "].location != parent.location + '" + over_href + "') { parent.frames[" + over_target_num + "].location='" + over_href + "' }";
- // string javascript = "parent." + target + ".location='" + href + "'";
- temp += "onMouseOver=\"" + javascript + "\" ";
- temp += ">" + text + "</A>";
- return temp;
-}
-
-string frameRef(string href, string target, string target_num, string text)
-{
- return frameRef(href, target, href, target_num, text);
-}
-
-
-void StateMachine::writeHTMLFiles(string path)
-{
- string filename;
- string component = getIdent();
-
- /*
- {
- ostringstream out;
- out << "<html>" << endl;
- out << "<head>" << endl;
- out << "<title>" << component << "</title>" << endl;
- out << "</head>" << endl;
- out << "<frameset rows=\"30,30,*\" frameborder=\"1\">" << endl;
- out << " <frame name=\"Status\" src=\"empty.html\" marginheight=\"1\">" << endl;
- out << " <frame name=\"Table\" src=\"" << component << "_table.html\" marginheight=\"1\">" << endl;
- out << "</frameset>" << endl;
- out << "</html>" << endl;
- conditionally_write_file(path + component + ".html", out);
- }
- */
-
- // Create table with no row hilighted
- {
- ostringstream out;
- printHTMLTransitions(out, numStates()+1);
-
- // -- Write file
- filename = component + "_table.html";
- conditionally_write_file(path + filename, out);
- }
-
- // Generate transition tables
- for(int i=0; i<numStates(); i++) {
- ostringstream out;
- printHTMLTransitions(out, i);
-
- // -- Write file
- filename = component + "_table_" + getState(i).getIdent() + ".html";
- conditionally_write_file(path + filename, out);
- }
-
- // Generate action descriptions
- for(int i=0; i<numActions(); i++) {
- ostringstream out;
- createHTMLSymbol(getAction(i), "Action", out);
-
- // -- Write file
- filename = component + "_action_" + getAction(i).getIdent() + ".html";
- conditionally_write_file(path + filename, out);
- }
-
- // Generate state descriptions
- for(int i=0; i<numStates(); i++) {
- ostringstream out;
- createHTMLSymbol(getState(i), "State", out);
-
- // -- Write file
- filename = component + "_State_" + getState(i).getIdent() + ".html";
- conditionally_write_file(path + filename, out);
- }
-
- // Generate event descriptions
- for(int i=0; i<numEvents(); i++) {
- ostringstream out;
- createHTMLSymbol(getEvent(i), "Event", out);
-
- // -- Write file
- filename = component + "_Event_" + getEvent(i).getIdent() + ".html";
- conditionally_write_file(path + filename, out);
- }
-}
-
-void StateMachine::printHTMLTransitions(ostream& out, int active_state)
-{
- // -- Prolog
- out << "<HTML><BODY link=\"blue\" vlink=\"blue\">" << endl;
-
- // -- Header
- out << "<H1 align=\"center\">" << formatHTMLShorthand(getShorthand()) << ": " << endl;
- Vector<StateMachine*> machine_vec = g_sym_table.getStateMachines();
- for (int i=0; i<machine_vec.size(); i++) {
- StateMachine* type = machine_vec[i];
- if (i != 0) {
- out << " - ";
- }
- if (type == this) {
- out << type->getIdent() << endl;
- } else {
- out << "<A target=\"Table\"href=\"" + type->getIdent() + "_table.html\">" + type->getIdent() + "</A> " << endl;
- }
- }
- out << "</H1>" << endl;
-
- // -- Table header
- out << "<TABLE border=1>" << endl;
-
- // -- Column headers
- out << "<TR>" << endl;
-
- // -- First column header
- out << " <TH> </TH>" << endl;
-
- for(int event = 0; event < numEvents(); event++ ) {
- out << " <TH bgcolor=white>";
- out << frameRef(getIdent() + "_Event_" + getEvent(event).getIdent() + ".html", "Status", "1", formatHTMLShorthand(getEvent(event).getShorthand()));
- out << "</TH>" << endl;
- }
-
- out << "</TR>" << endl;
-
- // -- Body of table
- for(int state = 0; state < numStates(); state++ ) {
- out << "<TR>" << endl;
-
- // -- Each row
- if (state == active_state) {
- out << " <TH bgcolor=yellow>";
- } else {
- out << " <TH bgcolor=white>";
- }
-
- string click_href = getIdent() + "_table_" + getState(state).getIdent() + ".html";
- string text = formatHTMLShorthand(getState(state).getShorthand());
-
- out << frameRef(click_href, "Table", getIdent() + "_State_" + getState(state).getIdent() + ".html", "1", formatHTMLShorthand(getState(state).getShorthand()));
- out << "</TH>" << endl;
-
- // -- One column for each event
- for(int event = 0; event < numEvents(); event++ ) {
- const Transition* trans_ptr = getTransPtr(state, event);
-
- if( trans_ptr != NULL ) {
- bool stall_action = false;
- string nextState;
- string actions_str;
-
- // -- Get the actions
- // actions = trans_ptr->getActionShorthands();
- const Vector<Action*> actions = trans_ptr->getActions();
- for (int action=0; action < actions.size(); action++) {
- if ((actions[action]->getIdent() == "z_stall") ||
- (actions[action]->getIdent() == "zz_recycleMandatoryQueue")) {
- stall_action = true;
- }
- actions_str += " ";
- actions_str += frameRef(getIdent() + "_action_" + actions[action]->getIdent() + ".html", "Status", "1",
- formatHTMLShorthand(actions[action]->getShorthand()));
- actions_str += "\n";
- }
-
- // -- Get the next state
- if (trans_ptr->getNextStatePtr()->getIdent() != getState(state).getIdent()) {
- string click_href = getIdent() + "_table_" + trans_ptr->getNextStatePtr()->getIdent() + ".html";
- nextState = frameRef(click_href, "Table", getIdent() + "_State_" + trans_ptr->getNextStatePtr()->getIdent() + ".html", "1",
- formatHTMLShorthand(trans_ptr->getNextStateShorthand()));
- } else {
- nextState = "";
- }
-
- // -- Print out "actions/next-state"
- if (stall_action) {
- if (state == active_state) {
- out << " <TD bgcolor=#C0C000>";
- } else {
- out << " <TD bgcolor=lightgrey>";
- }
- } else if (active_state < numStates() && (trans_ptr->getNextStatePtr()->getIdent() == getState(active_state).getIdent())) {
- out << " <TD bgcolor=aqua>";
- } else if (state == active_state) {
- out << " <TD bgcolor=yellow>";
- } else {
- out << " <TD bgcolor=white>";
- }
-
- out << actions_str;
- if ((nextState.length() != 0) && (actions_str.length() != 0)) {
- out << "/";
- }
- out << nextState;
- out << "</TD>" << endl;
- } else {
- // This is the no transition case
- if (state == active_state) {
- out << " <TD bgcolor=#C0C000>&nbsp;</TD>" << endl;
- } else {
- out << " <TD bgcolor=lightgrey>&nbsp;</TD>" << endl;
- }
- }
- }
- // -- Each row
- if (state == active_state) {
- out << " <TH bgcolor=yellow>";
- } else {
- out << " <TH bgcolor=white>";
- }
-
- click_href = getIdent() + "_table_" + getState(state).getIdent() + ".html";
- text = formatHTMLShorthand(getState(state).getShorthand());
-
- out << frameRef(click_href, "Table", getIdent() + "_State_" + getState(state).getIdent() + ".html", "1", formatHTMLShorthand(getState(state).getShorthand()));
- out << "</TH>" << endl;
-
- out << "</TR>" << endl;
- }
-
- // -- Column footer
- out << "<TR>" << endl;
- out << " <TH> </TH>" << endl;
-
- for(int i = 0; i < numEvents(); i++ ) {
- out << " <TH bgcolor=white>";
- out << frameRef(getIdent() + "_Event_" + getEvent(i).getIdent() + ".html", "Status", "1", formatHTMLShorthand(getEvent(i).getShorthand()));
- out << "</TH>" << endl;
- }
- out << "</TR>" << endl;
-
- // -- Epilog
- out << "</TABLE>" << endl;
- out << "</BODY></HTML>" << endl;
-}
-
-
diff --git a/src/mem/slicc/symbols/StateMachine.hh b/src/mem/slicc/symbols/StateMachine.hh
deleted file mode 100644
index f5f3ab073..000000000
--- a/src/mem/slicc/symbols/StateMachine.hh
+++ /dev/null
@@ -1,156 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- * */
-
-#ifndef STATEMACHINE_H
-#define STATEMACHINE_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/gems_common/Vector.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/slicc/symbols/Symbol.hh"
-#include <list>
-
-using namespace std;
-
-class Transition;
-class Event;
-class State;
-class Action;
-class Var;
-class Func;
-class FormalParamAST;
-
-class StateMachine : public Symbol {
-public:
- // Constructors
- StateMachine(string ident, const Location& location, const Map<string, string>& pairs, Vector<FormalParamAST*>* config_parameters);
-
- // Destructor
- ~StateMachine();
-
- // Public Methods
-
- // Add items to the state machine
- // void setMachine(string ident, const Map<string, string>& pairs);
- void addState(State* state_ptr);
- void addEvent(Event* event_ptr);
- void addAction(Action* action_ptr);
- void addTransition(Transition* trans_ptr);
- void addInPort(Var* var) { m_in_ports.insertAtBottom(var); }
- void addFunc(Func* func);
- void addObj(Var* obj) { m_objs.insertAtBottom(obj); }
-
- // Accessors to vectors
- const State& getState(int index) const { return *m_states[index]; }
- const Event& getEvent(int index) const { return *m_events[index]; }
- const Action& getAction(int index) const { return *m_actions[index]; }
- const Transition& getTransition(int index) const { return *m_transitions[index]; }
- const Transition* getTransPtr(int stateIndex, int eventIndex) const;
- const Var& getObject(int index) const { return *m_objs[index]; }
-
- // Accessors for size of vectors
- int numStates() const { return m_states.size(); }
- int numEvents() const { return m_events.size(); }
- int numActions() const { return m_actions.size(); }
- int numTransitions() const { return m_transitions.size(); }
- int numObjects() const { return m_objs.size(); }
-
- void buildTable(); // Needs to be called before accessing the table
-
- // Code generator methods
- void writeCFiles(string path) ;
- void writeHTMLFiles(string path) ;
-
- void print(ostream& out) const { out << "[StateMachine: " << toString() << "]" << endl; }
-private:
-
- Vector<FormalParamAST*>* m_config_parameters;
-
- // Private Methods
- void checkForDuplicate(const Symbol& sym) const;
-
- int getStateIndex(State* state_ptr) const { return m_state_map.lookup(state_ptr); }
- int getEventIndex(Event* event_ptr) const { return m_event_map.lookup(event_ptr); }
-
- // Private copy constructor and assignment operator
- // StateMachine(const StateMachine& obj);
- // StateMachine& operator=(const StateMachine& obj);
-
- void printControllerH(ostream& out, string component) ;
- void printControllerC(ostream& out, string component) ;
- void printCWakeup(ostream& out, string component) ;
- void printCSwitch(ostream& out, string component) ;
- void printProfilerH(ostream& out, string component) ;
- void printProfilerC(ostream& out, string component) ;
-
- void printHTMLTransitions(ostream& out, int active_state) ;
-
- // Data Members (m_ prefix)
- Vector<State*> m_states;
- Vector<Event*> m_events;
- Vector<Action*> m_actions;
- Vector<Transition*> m_transitions;
- Vector<Func*> m_internal_func_vec;
-
- Map<State*, int> m_state_map;
- Map<Event*, int> m_event_map;
-
- Vector<Var*> m_in_ports;
-
- Vector<Var*> m_objs;
-
- // Table variables
- bool m_table_built;
- Vector<Vector<Transition*> > m_table;
-
- //added by SS
- std::vector<std::string> m_message_buffer_names;
-
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const StateMachine& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const StateMachine& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //STATEMACHINE_H
diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py
new file mode 100644
index 000000000..e54d6a435
--- /dev/null
+++ b/src/mem/slicc/symbols/StateMachine.py
@@ -0,0 +1,1222 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter, orderdict
+
+from slicc.symbols.Symbol import Symbol
+from slicc.symbols.Var import Var
+import slicc.generate.html as html
+
+class StateMachine(Symbol):
+ def __init__(self, symtab, ident, location, pairs, config_parameters):
+ super(StateMachine, self).__init__(symtab, ident, location, pairs)
+ self.table = None
+ self.config_parameters = config_parameters
+ for param in config_parameters:
+ var = Var(symtab, param.name, location, param.type_ast.type,
+ "m_%s" % param.name, {}, self)
+ self.symtab.registerSym(param.name, var)
+
+ self.states = orderdict()
+ self.events = orderdict()
+ self.actions = orderdict()
+ self.transitions = []
+ self.in_ports = []
+ self.functions = []
+ self.objects = []
+
+ self.message_buffer_names = []
+
+ def __repr__(self):
+ return "[StateMachine: %s]" % self.ident
+
+ def addState(self, state):
+ assert self.table is None
+ self.states[state.ident] = state
+
+ def addEvent(self, event):
+ assert self.table is None
+ self.events[event.ident] = event
+
+ def addAction(self, action):
+ assert self.table is None
+
+ # Check for duplicate action
+ for other in self.actions.itervalues():
+ if action.ident == other.ident:
+ a.warning("Duplicate action definition: %s" % a.ident)
+ action.error("Duplicate action definition: %s" % action.ident)
+ if action.short == other.short:
+ other.warning("Duplicate action shorthand: %s" % other.ident)
+ other.warning(" shorthand = %s" % other.short)
+ action.warning("Duplicate action shorthand: %s" % action.ident)
+ action.error(" shorthand = %s" % action.short)
+
+ self.actions[action.ident] = action
+
+ def addTransition(self, trans):
+ assert self.table is None
+ self.transitions.append(trans)
+
+ def addInPort(self, var):
+ self.in_ports.append(var)
+
+ def addFunc(self, func):
+ # register func in the symbol table
+ self.symtab.registerSym(str(func), func)
+ self.functions.append(func)
+
+ def addObject(self, obj):
+ self.objects.append(obj)
+
+ # Needs to be called before accessing the table
+ def buildTable(self):
+ assert self.table is None
+
+ table = {}
+
+ for trans in self.transitions:
+ # Track which actions we touch so we know if we use them
+ # all -- really this should be done for all symbols as
+ # part of the symbol table, then only trigger it for
+ # Actions, States, Events, etc.
+
+ for action in trans.actions:
+ action.used = True
+
+ index = (trans.state, trans.event)
+ if index in table:
+ table[index].warning("Duplicate transition: %s" % table[index])
+ trans.error("Duplicate transition: %s" % trans)
+ table[index] = trans
+
+ # Look at all actions to make sure we used them all
+ for action in self.actions.itervalues():
+ if not action.used:
+ error_msg = "Unused action: %s" % action.ident
+ if "desc" in action:
+ error_msg += ", " + action.desc
+ action.warning(error_msg)
+ self.table = table
+
+ def writeCodeFiles(self, path):
+ self.printControllerHH(path)
+ self.printControllerCC(path)
+ self.printCSwitch(path)
+ self.printCWakeup(path)
+ self.printProfilerCC(path)
+ self.printProfilerHH(path)
+
+ for func in self.functions:
+ func.writeCodeFiles(path)
+
+ def printControllerHH(self, path):
+ '''Output the method declarations for the class declaration'''
+ code = code_formatter()
+ ident = self.ident
+ c_ident = "%s_Controller" % self.ident
+
+ self.message_buffer_names = []
+
+ code('''
+/** \\file $ident.hh
+ *
+ * Auto generated C++ code started by $__file__:$__line__
+ * Created by slicc definition of Module "${{self.short}}"
+ */
+
+#ifndef ${ident}_CONTROLLER_H
+#define ${ident}_CONTROLLER_H
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/common/Consumer.hh"
+#include "mem/ruby/slicc_interface/AbstractController.hh"
+#include "mem/protocol/TransitionResult.hh"
+#include "mem/protocol/Types.hh"
+#include "mem/protocol/${ident}_Profiler.hh"
+''')
+
+ seen_types = set()
+ for var in self.objects:
+ if var.type.ident not in seen_types:
+ code('#include "mem/protocol/${{var.type.c_ident}}.hh"')
+ seen_types.add(var.type.ident)
+
+ # for adding information to the protocol debug trace
+ code('''
+extern stringstream ${ident}_transitionComment;
+
+class $c_ident : public AbstractController {
+#ifdef CHECK_COHERENCE
+#endif /* CHECK_COHERENCE */
+public:
+ $c_ident(const string & name);
+ static int getNumControllers();
+ void init(Network* net_ptr, const vector<string> & argv);
+ MessageBuffer* getMandatoryQueue() const;
+ const int & getVersion() const;
+ const string toString() const;
+ const string getName() const;
+ const MachineType getMachineType() const;
+ void print(ostream& out) const;
+ void printConfig(ostream& out) const;
+ void wakeup();
+ void set_atomic(Address addr);
+ void started_writes();
+ void clear_atomic();
+ void printStats(ostream& out) const { s_profiler.dumpStats(out); }
+ void clearStats() { s_profiler.clearStats(); }
+private:
+''')
+
+ code.indent()
+ # added by SS
+ for param in self.config_parameters:
+ code('int m_${{param.ident}};')
+
+ if self.ident == "L1Cache":
+ code('''
+int servicing_atomic;
+bool started_receiving_writes;
+Address locked_read_request1;
+Address locked_read_request2;
+Address locked_read_request3;
+Address locked_read_request4;
+int read_counter;
+''')
+
+ code('''
+int m_number_of_TBEs;
+
+TransitionResult doTransition(${ident}_Event event, ${ident}_State state, const Address& addr); // in ${ident}_Transitions.cc
+TransitionResult doTransitionWorker(${ident}_Event event, ${ident}_State state, ${ident}_State& next_state, const Address& addr); // in ${ident}_Transitions.cc
+string m_name;
+int m_transitions_per_cycle;
+int m_buffer_size;
+int m_recycle_latency;
+map< string, string > m_cfg;
+NodeID m_version;
+Network* m_net_ptr;
+MachineID m_machineID;
+${ident}_Profiler s_profiler;
+static int m_num_controllers;
+// Internal functions
+''')
+
+ for func in self.functions:
+ proto = func.prototype
+ if proto:
+ code('$proto')
+
+ code('''
+
+// Actions
+''')
+ for action in self.actions.itervalues():
+ code('/** \\brief ${{action.desc}} */')
+ code('void ${{action.ident}}(const Address& addr);')
+
+ # the controller internal variables
+ code('''
+
+// Object
+''')
+ for var in self.objects:
+ th = var.get("template_hack", "")
+ code('${{var.type.c_ident}}$th* m_${{var.c_ident}}_ptr;')
+
+ if var.type.ident == "MessageBuffer":
+ self.message_buffer_names.append("m_%s_ptr" % var.c_ident)
+
+ code.dedent()
+ code('};')
+ code('#endif // ${ident}_CONTROLLER_H')
+ code.write(path, '%s.hh' % c_ident)
+
+ def printControllerCC(self, path):
+ '''Output the actions for performing the actions'''
+
+ code = code_formatter()
+ ident = self.ident
+ c_ident = "%s_Controller" % self.ident
+
+ code('''
+/** \\file $ident.cc
+ *
+ * Auto generated C++ code started by $__file__:$__line__
+ * Created by slicc definition of Module "${{self.short}}"
+ */
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/slicc_interface/RubySlicc_includes.hh"
+#include "mem/protocol/${ident}_Controller.hh"
+#include "mem/protocol/${ident}_State.hh"
+#include "mem/protocol/${ident}_Event.hh"
+#include "mem/protocol/Types.hh"
+#include "mem/ruby/system/System.hh"
+''')
+
+ # include object classes
+ seen_types = set()
+ for var in self.objects:
+ if var.type.ident not in seen_types:
+ code('#include "mem/protocol/${{var.type.c_ident}}.hh"')
+ seen_types.add(var.type.ident)
+
+ code('''
+int $c_ident::m_num_controllers = 0;
+
+stringstream ${ident}_transitionComment;
+#define APPEND_TRANSITION_COMMENT(str) (${ident}_transitionComment << str)
+/** \\brief constructor */
+$c_ident::$c_ident(const string &name)
+ : m_name(name)
+{
+''')
+ code.indent()
+ if self.ident == "L1Cache":
+ code('''
+servicing_atomic = 0;
+started_receiving_writes = false;
+locked_read_request1 = Address(-1);
+locked_read_request2 = Address(-1);
+locked_read_request3 = Address(-1);
+locked_read_request4 = Address(-1);
+read_counter = 0;
+''')
+
+ code('m_num_controllers++;')
+ for var in self.objects:
+ if var.ident.find("mandatoryQueue") >= 0:
+ code('m_${{var.c_ident}}_ptr = new ${{var.type.c_ident}}();')
+
+ code.dedent()
+ code('''
+}
+
+void $c_ident::init(Network *net_ptr, const vector<string> &argv)
+{
+ for (size_t i = 0; i < argv.size(); i += 2) {
+ if (argv[i] == "version")
+ m_version = atoi(argv[i+1].c_str());
+ else if (argv[i] == "transitions_per_cycle")
+ m_transitions_per_cycle = atoi(argv[i+1].c_str());
+ else if (argv[i] == "buffer_size")
+ m_buffer_size = atoi(argv[i+1].c_str());
+ else if (argv[i] == "recycle_latency")
+ m_recycle_latency = atoi(argv[i+1].c_str());
+ else if (argv[i] == "number_of_TBEs")
+ m_number_of_TBEs = atoi(argv[i+1].c_str());
+''')
+
+ code.indent()
+ code.indent()
+ for param in self.config_parameters:
+ code('else if (argv[i] == "${{param.name}}")')
+ if param.type_ast.type.ident == "int":
+ code(' m_${{param.name}} = atoi(argv[i+1].c_str());')
+ else:
+ self.error("only int parameters are supported right now")
+ code.dedent()
+ code.dedent()
+ code('''
+ }
+
+ m_net_ptr = net_ptr;
+ m_machineID.type = MachineType_${ident};
+ m_machineID.num = m_version;
+ for (size_t i = 0; i < argv.size(); i += 2) {
+ if (argv[i] != "version")
+ m_cfg[argv[i]] = argv[i+1];
+ }
+
+ // Objects
+ s_profiler.setVersion(m_version);
+''')
+
+ code.indent()
+ for var in self.objects:
+ vtype = var.type
+ vid = "m_%s_ptr" % var.c_ident
+ if "network" not in var:
+ # Not a network port object
+ if "primitive" in vtype:
+ code('$vid = new ${{vtype.c_ident}};')
+ if "default" in var:
+ code('(*$vid) = ${{var["default"]}};')
+ else:
+ # Normal Object
+ # added by SS
+ if "factory" in var:
+ code('$vid = ${{var["factory"]}};')
+ elif var.ident.find("mandatoryQueue") < 0:
+ th = var.get("template_hack", "")
+ expr = "%s = new %s%s" % (vid, vtype.c_ident, th)
+
+ args = ""
+ if "non_obj" not in vtype and not vtype.isEnumeration:
+ if expr.find("TBETable") >= 0:
+ args = "m_number_of_TBEs"
+ else:
+ args = var.get("constructor_hack", "")
+ args = "(%s)" % args
+
+ code('$expr$args;')
+ else:
+ code(';')
+
+ code('assert($vid != NULL);')
+
+ if "default" in var:
+ code('(*$vid) = ${{var["default"]}}; // Object default')
+ elif "default" in vtype:
+ code('(*$vid) = ${{vtype["default"]}}; // Type ${{vtype.ident}} default')
+
+ # Set ordering
+ if "ordered" in var and "trigger_queue" not in var:
+ # A buffer
+ code('$vid->setOrdering(${{var["ordered"]}});')
+
+ # Set randomization
+ if "random" in var:
+ # A buffer
+ code('$vid->setRandomization(${{var["random"]}});')
+
+ # Set Priority
+ if vtype.isBuffer and \
+ "rank" in var and "trigger_queue" not in var:
+ code('$vid->setPriority(${{var["rank"]}});')
+ else:
+ # Network port object
+ network = var["network"]
+ ordered = var["ordered"]
+ vnet = var["virtual_network"]
+
+ assert var.machine is not None
+ code('''
+$vid = m_net_ptr->get${network}NetQueue(m_version+MachineType_base_number(string_to_MachineType("${{var.machine.ident}}")), $ordered, $vnet);
+''')
+
+ code('assert($vid != NULL);')
+
+ # Set ordering
+ if "ordered" in var:
+ # A buffer
+ code('$vid->setOrdering(${{var["ordered"]}});')
+
+ # Set randomization
+ if "random" in var:
+ # A buffer
+ code('$vid->setRandomization(${{var["random"]}})')
+
+ # Set Priority
+ if "rank" in var:
+ code('$vid->setPriority(${{var["rank"]}})')
+
+ # Set buffer size
+ if vtype.isBuffer:
+ code('''
+if (m_buffer_size > 0) {
+ $vid->setSize(m_buffer_size);
+}
+''')
+
+ # set description (may be overriden later by port def)
+ code('$vid->setDescription("[Version " + int_to_string(m_version) + ", ${ident}, name=${{var.c_ident}}]");')
+
+ # Set the queue consumers
+ code.insert_newline()
+ for port in self.in_ports:
+ code('${{port.code}}.setConsumer(this);')
+
+ # Set the queue descriptions
+ code.insert_newline()
+ for port in self.in_ports:
+ code('${{port.code}}.setDescription("[Version " + int_to_string(m_version) + ", $ident, $port]");')
+
+ # Initialize the transition profiling
+ code.insert_newline()
+ for trans in self.transitions:
+ # Figure out if we stall
+ stall = False
+ for action in trans.actions:
+ if action.ident == "z_stall":
+ stall = True
+
+ # Only possible if it is not a 'z' case
+ if not stall:
+ state = "%s_State_%s" % (self.ident, trans.state.ident)
+ event = "%s_Event_%s" % (self.ident, trans.event.ident)
+ code('s_profiler.possibleTransition($state, $event);')
+
+ # added by SS to initialize recycle_latency of message buffers
+ for buf in self.message_buffer_names:
+ code("$buf->setRecycleLatency(m_recycle_latency);")
+
+ code.dedent()
+ code('}')
+
+ has_mandatory_q = False
+ for port in self.in_ports:
+ if port.code.find("mandatoryQueue_ptr") >= 0:
+ has_mandatory_q = True
+
+ if has_mandatory_q:
+ mq_ident = "m_%s_mandatoryQueue_ptr" % self.ident
+ else:
+ mq_ident = "NULL"
+
+ code('''
+int $c_ident::getNumControllers() {
+ return m_num_controllers;
+}
+
+MessageBuffer* $c_ident::getMandatoryQueue() const {
+ return $mq_ident;
+}
+
+const int & $c_ident::getVersion() const{
+ return m_version;
+}
+
+const string $c_ident::toString() const{
+ return "$c_ident";
+}
+
+const string $c_ident::getName() const{
+ return m_name;
+}
+const MachineType $c_ident::getMachineType() const{
+ return MachineType_${ident};
+}
+
+void $c_ident::print(ostream& out) const { out << "[$c_ident " << m_version << "]"; }
+
+void $c_ident::printConfig(ostream& out) const {
+ out << "$c_ident config: " << m_name << endl;
+ out << " version: " << m_version << endl;
+ for (map<string, string>::const_iterator it = m_cfg.begin(); it != m_cfg.end(); it++) {
+ out << " " << (*it).first << ": " << (*it).second << endl;
+ }
+}
+
+// Actions
+''')
+
+ for action in self.actions.itervalues():
+ if "c_code" not in action:
+ continue
+
+ code('''
+/** \\brief ${{action.desc}} */
+void $c_ident::${{action.ident}}(const Address& addr)
+{
+ DEBUG_MSG(GENERATED_COMP, HighPrio, "executing");
+ ${{action["c_code"]}}
+}
+
+''')
+ code.write(path, "%s.cc" % c_ident)
+
+ def printCWakeup(self, path):
+ '''Output the wakeup loop for the events'''
+
+ code = code_formatter()
+ ident = self.ident
+
+ code('''
+// Auto generated C++ code started by $__file__:$__line__
+// ${ident}: ${{self.short}}
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/slicc_interface/RubySlicc_includes.hh"
+#include "mem/protocol/${ident}_Controller.hh"
+#include "mem/protocol/${ident}_State.hh"
+#include "mem/protocol/${ident}_Event.hh"
+#include "mem/protocol/Types.hh"
+#include "mem/ruby/system/System.hh"
+
+void ${ident}_Controller::wakeup()
+{
+
+ int counter = 0;
+ while (true) {
+ // Some cases will put us into an infinite loop without this limit
+ assert(counter <= m_transitions_per_cycle);
+ if (counter == m_transitions_per_cycle) {
+ g_system_ptr->getProfiler()->controllerBusy(m_machineID); // Count how often we\'re fully utilized
+ g_eventQueue_ptr->scheduleEvent(this, 1); // Wakeup in another cycle and try again
+ break;
+ }
+''')
+
+ code.indent()
+ code.indent()
+
+ # InPorts
+ #
+ # Find the position of the mandatory queue in the vector so
+ # that we can print it out first
+
+ mandatory_q = None
+ if self.ident == "L1Cache":
+ for i,port in enumerate(self.in_ports):
+ assert "c_code_in_port" in port
+ if str(port).find("mandatoryQueue_in") >= 0:
+ assert mandatory_q is None
+ mandatory_q = port
+
+ assert mandatory_q is not None
+
+ # print out the mandatory queue here
+ port = mandatory_q
+ code('// ${ident}InPort $port')
+ output = port["c_code_in_port"]
+
+ pos = output.find("TransitionResult result = doTransition((L1Cache_mandatory_request_type_to_event(((*in_msg_ptr)).m_Type)), L1Cache_getState(addr), addr);")
+ assert pos >= 0
+ atomics_string = '''
+if ((((*in_msg_ptr)).m_Type) == CacheRequestType_ATOMIC) {
+ if (servicing_atomic == 0) {
+ if (locked_read_request1 == Address(-1)) {
+ assert(read_counter == 0);
+ locked_read_request1 = addr;
+ assert(read_counter == 0);
+ read_counter++;
+ }
+ else if (addr == locked_read_request1) {
+ ; // do nothing
+ }
+ else {
+ assert(0); // should never be here if servicing one request at a time
+ }
+ }
+ else if (!started_receiving_writes) {
+ if (servicing_atomic == 1) {
+ if (locked_read_request2 == Address(-1)) {
+ assert(locked_read_request1 != Address(-1));
+ assert(read_counter == 1);
+ locked_read_request2 = addr;
+ assert(read_counter == 1);
+ read_counter++;
+ }
+ else if (addr == locked_read_request2) {
+ ; // do nothing
+ }
+ else {
+ assert(0); // should never be here if servicing one request at a time
+ }
+ }
+ else if (servicing_atomic == 2) {
+ if (locked_read_request3 == Address(-1)) {
+ assert(locked_read_request1 != Address(-1));
+ assert(locked_read_request2 != Address(-1));
+ assert(read_counter == 1);
+ locked_read_request3 = addr;
+ assert(read_counter == 2);
+ read_counter++;
+ }
+ else if (addr == locked_read_request3) {
+ ; // do nothing
+ }
+ else {
+ assert(0); // should never be here if servicing one request at a time
+ }
+ }
+ else if (servicing_atomic == 3) {
+ if (locked_read_request4 == Address(-1)) {
+ assert(locked_read_request1 != Address(-1));
+ assert(locked_read_request2 != Address(-1));
+ assert(locked_read_request3 != Address(-1));
+ assert(read_counter == 1);
+ locked_read_request4 = addr;
+ assert(read_counter == 3);
+ read_counter++;
+ }
+ else if (addr == locked_read_request4) {
+ ; // do nothing
+ }
+ else {
+ assert(0); // should never be here if servicing one request at a time
+ }
+ }
+ else {
+ assert(0);
+ }
+ }
+}
+else {
+ if (servicing_atomic > 0) {
+ // reset
+ servicing_atomic = 0;
+ read_counter = 0;
+ started_receiving_writes = false;
+ locked_read_request1 = Address(-1);
+ locked_read_request2 = Address(-1);
+ locked_read_request3 = Address(-1);
+ locked_read_request4 = Address(-1);
+ }
+}
+'''
+
+ output = output[:pos] + atomics_string + output[pos:]
+ code('$output')
+
+ for port in self.in_ports:
+ # don't print out mandatory queue twice
+ if port == mandatory_q:
+ continue
+
+ if ident == "L1Cache":
+ if str(port).find("forwardRequestNetwork_in") >= 0:
+ code('''
+bool postpone = false;
+if ((((*m_L1Cache_forwardToCache_ptr)).isReady())) {
+ const RequestMsg* in_msg_ptr;
+ in_msg_ptr = dynamic_cast<const RequestMsg*>(((*m_L1Cache_forwardToCache_ptr)).peek());
+ if ((((servicing_atomic == 1) && (locked_read_request1 == ((*in_msg_ptr)).m_Address)) ||
+ ((servicing_atomic == 2) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address)) ||
+ ((servicing_atomic == 3) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address || locked_read_request3 == ((*in_msg_ptr)).m_Address)) ||
+ ((servicing_atomic == 4) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address || locked_read_request3 == ((*in_msg_ptr)).m_Address || locked_read_request1 == ((*in_msg_ptr)).m_Address)))) {
+ postpone = true;
+ }
+}
+if (!postpone) {
+''')
+ code.indent()
+ code('// ${ident}InPort $port')
+ code('${{port["c_code_in_port"]}}')
+ code.dedent()
+
+ if ident == "L1Cache":
+ if str(port).find("forwardRequestNetwork_in") >= 0:
+ code.dedent()
+ code('}')
+ code.indent()
+ code('')
+
+ code.dedent()
+ code.dedent()
+ code('''
+ break; // If we got this far, we have nothing left todo
+ }
+}
+''')
+
+ if self.ident == "L1Cache":
+ code('''
+void ${ident}_Controller::set_atomic(Address addr)
+{
+ servicing_atomic++;
+}
+
+void ${ident}_Controller::started_writes()
+{
+ started_receiving_writes = true;
+}
+
+void ${ident}_Controller::clear_atomic()
+{
+ assert(servicing_atomic > 0);
+ read_counter--;
+ servicing_atomic--;
+ if (read_counter == 0) {
+ servicing_atomic = 0;
+ started_receiving_writes = false;
+ locked_read_request1 = Address(-1);
+ locked_read_request2 = Address(-1);
+ locked_read_request3 = Address(-1);
+ locked_read_request4 = Address(-1);
+ }
+}
+''')
+ else:
+ code('''
+void ${ident}_Controller::started_writes()
+{
+ assert(0);
+}
+
+void ${ident}_Controller::set_atomic(Address addr)
+{
+ assert(0);
+}
+
+void ${ident}_Controller::clear_atomic()
+{
+ assert(0);
+}
+''')
+
+
+ code.write(path, "%s_Wakeup.cc" % self.ident)
+
+ def printCSwitch(self, path):
+ '''Output switch statement for transition table'''
+
+ code = code_formatter()
+ ident = self.ident
+
+ code('''
+// Auto generated C++ code started by $__file__:$__line__
+// ${ident}: ${{self.short}}
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/protocol/${ident}_Controller.hh"
+#include "mem/protocol/${ident}_State.hh"
+#include "mem/protocol/${ident}_Event.hh"
+#include "mem/protocol/Types.hh"
+#include "mem/ruby/system/System.hh"
+
+#define HASH_FUN(state, event) ((int(state)*${ident}_Event_NUM)+int(event))
+
+#define GET_TRANSITION_COMMENT() (${ident}_transitionComment.str())
+#define CLEAR_TRANSITION_COMMENT() (${ident}_transitionComment.str(""))
+
+TransitionResult ${ident}_Controller::doTransition(${ident}_Event event, ${ident}_State state, const Address& addr
+)
+{
+ ${ident}_State next_state = state;
+
+ DEBUG_NEWLINE(GENERATED_COMP, MedPrio);
+ DEBUG_MSG(GENERATED_COMP, MedPrio, *this);
+ DEBUG_EXPR(GENERATED_COMP, MedPrio, g_eventQueue_ptr->getTime());
+ DEBUG_EXPR(GENERATED_COMP, MedPrio,state);
+ DEBUG_EXPR(GENERATED_COMP, MedPrio,event);
+ DEBUG_EXPR(GENERATED_COMP, MedPrio,addr);
+
+ TransitionResult result = doTransitionWorker(event, state, next_state, addr);
+
+ if (result == TransitionResult_Valid) {
+ DEBUG_EXPR(GENERATED_COMP, MedPrio, next_state);
+ DEBUG_NEWLINE(GENERATED_COMP, MedPrio);
+ s_profiler.countTransition(state, event);
+ if (Debug::getProtocolTrace()) {
+ g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr,
+ ${ident}_State_to_string(state),
+ ${ident}_Event_to_string(event),
+ ${ident}_State_to_string(next_state), GET_TRANSITION_COMMENT());
+ }
+ CLEAR_TRANSITION_COMMENT();
+ ${ident}_setState(addr, next_state);
+
+ } else if (result == TransitionResult_ResourceStall) {
+ if (Debug::getProtocolTrace()) {
+ g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr,
+ ${ident}_State_to_string(state),
+ ${ident}_Event_to_string(event),
+ ${ident}_State_to_string(next_state),
+ "Resource Stall");
+ }
+ } else if (result == TransitionResult_ProtocolStall) {
+ DEBUG_MSG(GENERATED_COMP, HighPrio, "stalling");
+ DEBUG_NEWLINE(GENERATED_COMP, MedPrio);
+ if (Debug::getProtocolTrace()) {
+ g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr,
+ ${ident}_State_to_string(state),
+ ${ident}_Event_to_string(event),
+ ${ident}_State_to_string(next_state),
+ "Protocol Stall");
+ }
+ }
+
+ return result;
+}
+
+TransitionResult ${ident}_Controller::doTransitionWorker(${ident}_Event event, ${ident}_State state, ${ident}_State& next_state, const Address& addr
+)
+{
+ switch(HASH_FUN(state, event)) {
+''')
+
+ # This map will allow suppress generating duplicate code
+ cases = orderdict()
+
+ for trans in self.transitions:
+ case_string = "%s_State_%s, %s_Event_%s" % \
+ (self.ident, trans.state.ident, self.ident, trans.event.ident)
+
+ case = code_formatter()
+ # Only set next_state if it changes
+ if trans.state != trans.nextState:
+ ns_ident = trans.nextState.ident
+ case('next_state = ${ident}_State_${ns_ident};')
+
+ actions = trans.actions
+
+ # Check for resources
+ case_sorter = []
+ res = trans.resources
+ for key,val in res.iteritems():
+ if key.type.ident != "DNUCAStopTable":
+ val = '''
+if (!%s.areNSlotsAvailable(%s)) {
+ return TransitionResult_ResourceStall;
+}
+''' % (key.code, val)
+ case_sorter.append(val)
+
+
+ # Emit the code sequences in a sorted order. This makes the
+ # output deterministic (without this the output order can vary
+ # since Map's keys() on a vector of pointers is not deterministic
+ for c in sorted(case_sorter):
+ case("$c")
+
+ # Figure out if we stall
+ stall = False
+ for action in actions:
+ if action.ident == "z_stall":
+ stall = True
+ break
+
+ if stall:
+ case('return TransitionResult_ProtocolStall;')
+ else:
+ for action in actions:
+ case('${{action.ident}}(addr);')
+ case('return TransitionResult_Valid;')
+
+ case = str(case)
+
+ # Look to see if this transition code is unique.
+ if case not in cases:
+ cases[case] = []
+
+ cases[case].append(case_string)
+
+ # Walk through all of the unique code blocks and spit out the
+ # corresponding case statement elements
+ for case,transitions in cases.iteritems():
+ # Iterative over all the multiple transitions that share
+ # the same code
+ for trans in transitions:
+ code(' case HASH_FUN($trans):')
+ code(' {')
+ code(' $case')
+ code(' }')
+
+ code('''
+ default:
+ WARN_EXPR(m_version);
+ WARN_EXPR(g_eventQueue_ptr->getTime());
+ WARN_EXPR(addr);
+ WARN_EXPR(event);
+ WARN_EXPR(state);
+ ERROR_MSG(\"Invalid transition\");
+ }
+ return TransitionResult_Valid;
+}
+''')
+ code.write(path, "%s_Transitions.cc" % self.ident)
+
+ def printProfilerHH(self, path):
+ code = code_formatter()
+ ident = self.ident
+
+ code('''
+// Auto generated C++ code started by $__file__:$__line__
+// ${ident}: ${{self.short}}
+
+#ifndef ${ident}_PROFILER_H
+#define ${ident}_PROFILER_H
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/protocol/${ident}_State.hh"
+#include "mem/protocol/${ident}_Event.hh"
+
+class ${ident}_Profiler {
+ public:
+ ${ident}_Profiler();
+ void setVersion(int version);
+ void countTransition(${ident}_State state, ${ident}_Event event);
+ void possibleTransition(${ident}_State state, ${ident}_Event event);
+ void dumpStats(ostream& out) const;
+ void clearStats();
+
+ private:
+ int m_counters[${ident}_State_NUM][${ident}_Event_NUM];
+ int m_event_counters[${ident}_Event_NUM];
+ bool m_possible[${ident}_State_NUM][${ident}_Event_NUM];
+ int m_version;
+};
+
+#endif // ${ident}_PROFILER_H
+''')
+ code.write(path, "%s_Profiler.hh" % self.ident)
+
+ def printProfilerCC(self, path):
+ code = code_formatter()
+ ident = self.ident
+
+ code('''
+// Auto generated C++ code started by $__file__:$__line__
+// ${ident}: ${{self.short}}
+
+#include "mem/protocol/${ident}_Profiler.hh"
+
+${ident}_Profiler::${ident}_Profiler()
+{
+ for (int state = 0; state < ${ident}_State_NUM; state++) {
+ for (int event = 0; event < ${ident}_Event_NUM; event++) {
+ m_possible[state][event] = false;
+ m_counters[state][event] = 0;
+ }
+ }
+ for (int event = 0; event < ${ident}_Event_NUM; event++) {
+ m_event_counters[event] = 0;
+ }
+}
+void ${ident}_Profiler::setVersion(int version)
+{
+ m_version = version;
+}
+void ${ident}_Profiler::clearStats()
+{
+ for (int state = 0; state < ${ident}_State_NUM; state++) {
+ for (int event = 0; event < ${ident}_Event_NUM; event++) {
+ m_counters[state][event] = 0;
+ }
+ }
+
+ for (int event = 0; event < ${ident}_Event_NUM; event++) {
+ m_event_counters[event] = 0;
+ }
+}
+void ${ident}_Profiler::countTransition(${ident}_State state, ${ident}_Event event)
+{
+ assert(m_possible[state][event]);
+ m_counters[state][event]++;
+ m_event_counters[event]++;
+}
+void ${ident}_Profiler::possibleTransition(${ident}_State state, ${ident}_Event event)
+{
+ m_possible[state][event] = true;
+}
+void ${ident}_Profiler::dumpStats(ostream& out) const
+{
+ out << " --- ${ident} " << m_version << " ---" << endl;
+ out << " - Event Counts -" << endl;
+ for (int event = 0; event < ${ident}_Event_NUM; event++) {
+ int count = m_event_counters[event];
+ out << (${ident}_Event) event << " " << count << endl;
+ }
+ out << endl;
+ out << " - Transitions -" << endl;
+ for (int state = 0; state < ${ident}_State_NUM; state++) {
+ for (int event = 0; event < ${ident}_Event_NUM; event++) {
+ if (m_possible[state][event]) {
+ int count = m_counters[state][event];
+ out << (${ident}_State) state << " " << (${ident}_Event) event << " " << count;
+ if (count == 0) {
+ out << " <-- ";
+ }
+ out << endl;
+ }
+ }
+ out << endl;
+ }
+}
+''')
+ code.write(path, "%s_Profiler.cc" % self.ident)
+
+ # **************************
+ # ******* HTML Files *******
+ # **************************
+ def frameRef(self, click_href, click_target, over_href, over_target_num,
+ text):
+ code = code_formatter(fix_newlines=False)
+ 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>""")
+ return str(code)
+
+ def writeHTMLFiles(self, path):
+ # Create table with no row hilighted
+ self.printHTMLTransitions(path, None)
+
+ # Generate transition tables
+ for state in self.states.itervalues():
+ self.printHTMLTransitions(path, state)
+
+ # Generate action descriptions
+ for action in self.actions.itervalues():
+ name = "%s_action_%s.html" % (self.ident, action.ident)
+ code = html.createSymbol(action, "Action")
+ code.write(path, name)
+
+ # Generate state descriptions
+ for state in self.states.itervalues():
+ name = "%s_State_%s.html" % (self.ident, state.ident)
+ code = html.createSymbol(state, "State")
+ code.write(path, name)
+
+ # Generate event descriptions
+ for event in self.events.itervalues():
+ name = "%s_Event_%s.html" % (self.ident, event.ident)
+ code = html.createSymbol(event, "Event")
+ code.write(path, name)
+
+ def printHTMLTransitions(self, path, active_state):
+ code = code_formatter()
+
+ code('''
+<HTML><BODY link="blue" vlink="blue">
+
+<H1 align="center">${{html.formatShorthand(self.short)}}:
+''')
+ code.indent()
+ for i,machine in enumerate(self.symtab.getAllType(StateMachine)):
+ mid = machine.ident
+ if i != 0:
+ extra = " - "
+ else:
+ extra = ""
+ if machine == self:
+ code('$extra$mid')
+ else:
+ code('$extra<A target="Table" href="${mid}_table.html">$mid</A>')
+ code.dedent()
+
+ code("""
+</H1>
+
+<TABLE border=1>
+<TR>
+ <TH> </TH>
+""")
+
+ for event in self.events.itervalues():
+ href = "%s_Event_%s.html" % (self.ident, event.ident)
+ ref = self.frameRef(href, "Status", href, "1", event.short)
+ code('<TH bgcolor=white>$ref</TH>')
+
+ code('</TR>')
+ # -- Body of table
+ for state in self.states.itervalues():
+ # -- Each row
+ if state == active_state:
+ color = "yellow"
+ else:
+ color = "white"
+
+ click = "%s_table_%s.html" % (self.ident, state.ident)
+ over = "%s_State_%s.html" % (self.ident, state.ident)
+ text = html.formatShorthand(state.short)
+ ref = self.frameRef(click, "Table", over, "1", state.short)
+ code('''
+<TR>
+ <TH bgcolor=$color>$ref</TH>
+''')
+
+ # -- One column for each event
+ for event in self.events.itervalues():
+ trans = self.table.get((state,event), None)
+ if trans is None:
+ # This is the no transition case
+ if state == active_state:
+ color = "#C0C000"
+ else:
+ color = "lightgrey"
+
+ code('<TD bgcolor=$color>&nbsp;</TD>')
+ continue
+
+ next = trans.nextState
+ stall_action = False
+
+ # -- Get the actions
+ for action in trans.actions:
+ if action.ident == "z_stall" or \
+ action.ident == "zz_recycleMandatoryQueue":
+ stall_action = True
+
+ # -- Print out "actions/next-state"
+ if stall_action:
+ if state == active_state:
+ color = "#C0C000"
+ else:
+ color = "lightgrey"
+
+ elif active_state and next.ident == active_state.ident:
+ color = "aqua"
+ elif state == active_state:
+ color = "yellow"
+ else:
+ color = "white"
+
+ fix = code.nofix()
+ code('<TD bgcolor=$color>')
+ for action in trans.actions:
+ href = "%s_action_%s.html" % (self.ident, action.ident)
+ ref = self.frameRef(href, "Status", href, "1",
+ action.short)
+ code(' $ref\n')
+ if next != state:
+ if trans.actions:
+ code('/')
+ click = "%s_table_%s.html" % (self.ident, next.ident)
+ over = "%s_State_%s.html" % (self.ident, next.ident)
+ ref = self.frameRef(click, "Table", over, "1", next.short)
+ code("$ref")
+ code("</TD>\n")
+ code.fix(fix)
+
+ # -- Each row
+ if state == active_state:
+ color = "yellow"
+ else:
+ color = "white"
+
+ click = "%s_table_%s.html" % (self.ident, state.ident)
+ over = "%s_State_%s.html" % (self.ident, state.ident)
+ ref = self.frameRef(click, "Table", over, "1", state.short)
+ code('''
+ <TH bgcolor=$color>$ref</TH>
+</TR>
+''')
+ code('''
+<TR>
+ <TH> </TH>
+''')
+
+ for event in self.events.itervalues():
+ href = "%s_Event_%s.html" % (self.ident, event.ident)
+ ref = self.frameRef(href, "Status", href, "1", event.short)
+ code('<TH bgcolor=white>$ref</TH>')
+ code('''
+</TR>
+</TABLE>
+</BODY></HTML>
+''')
+
+
+ if active_state:
+ name = "%s_table_%s.html" % (self.ident, active_state.ident)
+ else:
+ name = "%s_table.html" % self.ident
+ code.write(path, name)
+
+__all__ = [ "StateMachine" ]
diff --git a/src/mem/slicc/symbols/Symbol.cc b/src/mem/slicc/symbols/Symbol.cc
deleted file mode 100644
index 25af5ad47..000000000
--- a/src/mem/slicc/symbols/Symbol.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- */
-
-#include "mem/slicc/symbols/Symbol.hh"
-
-Symbol::Symbol(string id, const Location& location, const Map<string, string>& pairs)
-{
- m_id = id;
- m_location = location;
- m_pairs = pairs;
- if (!existPair("short")) {
- addPair("short", m_id);
- }
- m_used = false;
-}
-
-Symbol::Symbol(string id, const Location& location)
-{
- m_id = id;
- m_location = location;
- if (!existPair("short")) {
- addPair("short", m_id);
- }
- m_used = false;
-}
-
-const string& Symbol::lookupPair(const string& key) const
-{
- if (!existPair(key)) {
- error("Value for pair '" + key + "' missing.");
- }
- return m_pairs.lookup(key);
-}
-
-void Symbol::addPair(const string& key, const string& value)
-{
- if (existPair(key)) {
- warning("Pair key '" + key + "' re-defined. new: '" + value + "' old: '" + lookupPair(key) + "'");
- }
- m_pairs.add(key, value);
-}
diff --git a/src/mem/slicc/symbols/Symbol.hh b/src/mem/slicc/symbols/Symbol.hh
deleted file mode 100644
index 4a1c5e44e..000000000
--- a/src/mem/slicc/symbols/Symbol.hh
+++ /dev/null
@@ -1,100 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- */
-
-#ifndef SYMBOL_H
-#define SYMBOL_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/slicc/ast/Location.hh"
-
-class Symbol {
-public:
- // Constructors
- Symbol(string id, const Location& location, const Map<string, string>& pairs);
- Symbol(string id, const Location& location);
- // Destructor
- virtual ~Symbol() { }
-
- // Public Methods
- void error(string err_msg) const { m_location.error(err_msg); }
- void warning(string err_msg) const { m_location.warning(err_msg); }
- const Location& getLocation() const { return m_location; }
-
- const string& toString() const { return m_id; }
-
- const string& getIdent() const { return m_id; }
- const string& getShorthand() const { return lookupPair("short"); }
- const string& getDescription() const { return lookupPair("desc"); }
-
- void markUsed() { m_used = true; }
- bool wasUsed() { return m_used; }
-
- bool existPair(const string& key) const { return m_pairs.exist(key); }
- const string& lookupPair(const string& key) const;
- void addPair(const string& key, const string& value);
-
- // virtual string getCode() const = 0;
- virtual void writeCFiles(string path) {}
- virtual void writeHTMLFiles(string path) {}
- virtual void print(ostream& out) const { out << "[Symbol: " << getIdent() << "]"; }
-
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- // Symbol(const Symbol& obj);
- // Symbol& operator=(const Symbol& obj);
-
- // Data Members (m_ prefix)
- string m_id;
- Map<string, string> m_pairs;
- Location m_location;
- bool m_used;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const Symbol& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const Symbol& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //SYMBOL_H
diff --git a/src/mem/slicc/symbols/Symbol.py b/src/mem/slicc/symbols/Symbol.py
new file mode 100644
index 000000000..b394fda44
--- /dev/null
+++ b/src/mem/slicc/symbols/Symbol.py
@@ -0,0 +1,78 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.util import PairContainer
+
+class Symbol(PairContainer):
+ def __init__(self, symtab, ident, location, pairs=None):
+ super(Symbol, self).__init__()
+
+ from slicc.util import Location
+ from slicc.symbols import SymbolTable
+ if not isinstance(symtab, SymbolTable): raise AttributeError
+ if not isinstance(ident, str): raise AttributeError
+ if not isinstance(location, Location): raise AttributeError
+
+ self.symtab = symtab
+ self.ident = ident
+ self.location = location
+ if pairs:
+ self.pairs.update(getattr(pairs, "pairs", pairs))
+ if "short" not in self:
+ self["short"] = self.ident
+ self.used = False
+
+ def __repr__(self):
+ return "[Symbol: %s]" % self.ident
+
+ def __str__(self):
+ return str(self.ident)
+
+ def __setitem__(self, key, value):
+ if key in self.pairs:
+ self.warning("Pair key '%s' re-defined. new: '%s' old: '%s'",
+ key, value, self.pairs[key])
+ super(Symbol, self).__setitem__(key, value)
+
+ @property
+ def short(self):
+ return self["short"]
+
+ @property
+ def desc(self):
+ return self["desc"]
+
+ def error(self, message, *args):
+ self.location.error(message, *args)
+
+ def warning(self, message, *args):
+ self.location.warning(message, *args)
+
+ def writeHTMLFiles(self, path):
+ pass
+
+__all__ = [ "Symbol" ]
diff --git a/src/mem/slicc/symbols/SymbolTable.cc b/src/mem/slicc/symbols/SymbolTable.cc
deleted file mode 100644
index 8af3685f8..000000000
--- a/src/mem/slicc/symbols/SymbolTable.cc
+++ /dev/null
@@ -1,327 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * SymbolTable.cc
- *
- * Description: See SymbolTable.hh
- *
- * $Id$
- *
- * */
-
-#include "mem/slicc/symbols/SymbolTable.hh"
-#include "mem/slicc/generator/fileio.hh"
-#include "mem/slicc/generator/html_gen.hh"
-#include "mem/slicc/generator/mif_gen.hh"
-#include "mem/slicc/symbols/Action.hh"
-
-SymbolTable g_sym_table;
-
-SymbolTable::SymbolTable()
-{
- m_sym_map_vec.setSize(1);
- m_depth = 0;
-
- {
- Map<string, string> pairs;
- pairs.add("enumeration", "yes");
- newSym(new Type("MachineType", Location(), pairs));
- }
-
- {
- Map<string, string> pairs;
- pairs.add("primitive", "yes");
- pairs.add("external", "yes");
- newSym(new Type("void", Location(), pairs));
- }
-}
-
-SymbolTable::~SymbolTable()
-{
- int size = m_sym_vec.size();
- for(int i=0; i<size; i++) {
- delete m_sym_vec[i];
- }
-}
-
-void SymbolTable::newSym(Symbol* sym_ptr)
-{
- registerSym(sym_ptr->toString(), sym_ptr);
- m_sym_vec.insertAtBottom(sym_ptr); // Holder for the allocated Sym objects.
-}
-
-void SymbolTable::newMachComponentSym(Symbol* sym_ptr)
-{
- // used to cheat-- that is, access components in other machines
- StateMachine* mach_ptr = getStateMachine("current_machine");
- if (mach_ptr != NULL) {
- m_machine_component_map_vec.lookup(mach_ptr->toString()).add(sym_ptr->toString(), sym_ptr);
- }
-}
-
-Var* SymbolTable::getMachComponentVar(string mach, string ident)
-{
- Symbol* s = m_machine_component_map_vec.lookup(mach).lookup(ident);
- return dynamic_cast<Var*>(s);
-}
-
-
-void SymbolTable::registerSym(string id, Symbol* sym_ptr)
-{
-
- // Check for redeclaration (in the current frame only)
- if (m_sym_map_vec[m_depth].exist(id)) {
- sym_ptr->error("Symbol '" + id + "' redeclared in same scope.");
- }
- // FIXME - warn on masking of a declaration in a previous frame
- m_sym_map_vec[m_depth].add(id, sym_ptr);
-}
-
-void SymbolTable::registerGlobalSym(string id, Symbol* sym_ptr)
-{
- // Check for redeclaration (global frame only)
- if (m_sym_map_vec[0].exist(id)) {
- sym_ptr->error("Global symbol '" + id + "' redeclared in global scope.");
- }
- m_sym_map_vec[0].add(id, sym_ptr);
-}
-
-Symbol* SymbolTable::getSym(string ident) const
-{
- for (int i=m_depth; i>=0; i--) {
- if (m_sym_map_vec[i].exist(ident)) {
- return m_sym_map_vec[i].lookup(ident);
- }
- }
- return NULL;
-}
-
-void SymbolTable::newCurrentMachine(StateMachine* sym_ptr)
-{
- registerGlobalSym(sym_ptr->toString(), sym_ptr);
- registerSym("current_machine", sym_ptr);
- m_sym_vec.insertAtBottom(sym_ptr); // Holder for the allocated Sym objects.
-
- Map<string, Symbol*> m;
- m_machine_component_map_vec.add(sym_ptr->toString(),m);
-
-}
-
-Type* SymbolTable::getType(string ident) const
-{
- return dynamic_cast<Type*>(getSym(ident));
-}
-
-Var* SymbolTable::getVar(string ident) const
-{
- return dynamic_cast<Var*>(getSym(ident));
-}
-
-Func* SymbolTable::getFunc(string ident) const
-{
- return dynamic_cast<Func*>(getSym(ident));
-}
-
-StateMachine* SymbolTable::getStateMachine(string ident) const
-{
- return dynamic_cast<StateMachine*>(getSym(ident));
-}
-
-void SymbolTable::pushFrame()
-{
- m_depth++;
- m_sym_map_vec.expand(1);
- m_sym_map_vec[m_depth].clear();
-}
-
-void SymbolTable::popFrame()
-{
- m_depth--;
- assert(m_depth >= 0);
- m_sym_map_vec.expand(-1);
-}
-
-void SymbolTable::writeCFiles(string path) const
-{
- int size = m_sym_vec.size();
- {
- // Write the Types.hh include file for the types
- ostringstream sstr;
- sstr << "/** Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< " */" << endl;
- sstr << endl;
- sstr << "#include \"mem/ruby/slicc_interface/RubySlicc_includes.hh\"" << endl;
- for(int i=0; i<size; i++) {
- Type* type = dynamic_cast<Type*>(m_sym_vec[i]);
- if (type != NULL && !type->isPrimitive()) {
- sstr << "#include \"mem/protocol/" << type->cIdent() << ".hh" << "\"" << endl;
- }
- }
- conditionally_write_file(path + "/Types.hh", sstr);
- }
-
- // Write all the symbols
- for(int i=0; i<size; i++) {
- m_sym_vec[i]->writeCFiles(path + '/');
- }
-
- writeControllerFactory(path);
-}
-
-void SymbolTable::writeControllerFactory(string path) const
-{
- ostringstream sstr;
- int size = m_sym_vec.size();
-
- sstr << "/** \\file ControllerFactory.hh " << endl;
- sstr << " * Auto generatred C++ code started by " << __FILE__ << ":" << __LINE__ << endl;
- sstr << " */" << endl << endl;
-
- sstr << "#ifndef CONTROLLERFACTORY_H" << endl;
- sstr << "#define CONTROLLERFACTORY_H" << endl;
- sstr << endl;
-
- Vector< string > controller_types;
-
- // includes
- sstr << "#include <string>" << endl;
- sstr << "class Network;" << endl;
- sstr << "class AbstractController;" << endl;
- sstr << endl;
-
- sstr << "class ControllerFactory {" << endl;
- sstr << "public:" << endl;
- sstr << " static AbstractController* createController(const std::string & controller_type, const std::string & name);" << endl;
- sstr << "};" << endl;
- sstr << endl;
-
- sstr << "#endif // CONTROLLERFACTORY_H" << endl;
- conditionally_write_file(path + "/ControllerFactory.hh", sstr);
-
- // ControllerFactory.cc file
-
- sstr.str("");
-
- sstr << "/** \\file ControllerFactory.cc " << endl;
- sstr << " * Auto generatred C++ code started by " << __FILE__ << ":" << __LINE__ << endl;
- sstr << " */" << endl << endl;
-
- // includes
- sstr << "#include \"mem/protocol/ControllerFactory.hh\"" << endl;
- sstr << "#include \"mem/ruby/slicc_interface/AbstractController.hh\"" << endl;
- sstr << "#include \"mem/protocol/MachineType.hh\"" << endl;
- for(int i=0; i<size; i++) {
- StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]);
- if (machine != NULL) {
- sstr << "#include \"mem/protocol/" << machine->getIdent() << "_Controller.hh\"" << endl;
- controller_types.insertAtBottom(machine->getIdent());
- }
- }
- sstr << endl;
-
- sstr << "AbstractController* ControllerFactory::createController(const std::string & controller_type, const std::string & name) {" << endl;
- for (int i=0;i<controller_types.size();i++) {
- sstr << " if (controller_type == \"" << controller_types[i] << "\")" << endl;
- sstr << " return new " << controller_types[i] << "_Controller(name);" << endl;
- }
- sstr << " assert(0); // invalid controller type" << endl;
- sstr << " return NULL;" << endl;
- sstr << "}" << endl;
- conditionally_write_file(path + "/ControllerFactory.cc", sstr);
-}
-
-Vector<StateMachine*> SymbolTable::getStateMachines() const
-{
- Vector<StateMachine*> machine_vec;
- int size = m_sym_vec.size();
- for(int i=0; i<size; i++) {
- StateMachine* type = dynamic_cast<StateMachine*>(m_sym_vec[i]);
- if (type != NULL) {
- machine_vec.insertAtBottom(type);
- }
- }
- return machine_vec;
-}
-
-void SymbolTable::writeHTMLFiles(string path) const
-{
- // Create index.html
- {
- ostringstream out;
- createHTMLindex(path, out);
- conditionally_write_file(path + "index.html", out);
- }
-
- // Create empty.html
- {
- ostringstream out;
- out << "<HTML></HTML>";
- conditionally_write_file(path + "empty.html", out);
- }
-
- // Write all the symbols
- int size = m_sym_vec.size();
- for(int i=0; i<size; i++) {
- m_sym_vec[i]->writeHTMLFiles(path);
- }
-}
-
-void write_file(string filename, ostringstream& sstr)
-{
- ofstream out;
-
- out.open(filename.c_str());
- out << sstr.str();
- out.close();
-}
-
-void SymbolTable::writeMIFFiles(string path) const
-{
- int size = m_sym_vec.size();
- for(int i=0; i<size; i++) {
- ostringstream states, events, actions, transitions;
- StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]);
- if (machine != NULL) {
- printStateTableMIF(*machine, states);
- write_file(path + machine->getIdent() + "_states.mif", states);
- printEventTableMIF(*machine, events);
- write_file(path + machine->getIdent() + "_events.mif", events);
- printActionTableMIF(*machine, actions);
- write_file(path + machine->getIdent() + "_actions.mif", actions);
- printTransitionTableMIF(*machine, transitions);
- write_file(path + machine->getIdent() + "_transitions.mif", transitions);
- }
- }
-}
-
-
-void SymbolTable::print(ostream& out) const
-{
- out << "[SymbolTable]"; // FIXME
-}
diff --git a/src/mem/slicc/symbols/SymbolTable.hh b/src/mem/slicc/symbols/SymbolTable.hh
deleted file mode 100644
index 90d3f48c3..000000000
--- a/src/mem/slicc/symbols/SymbolTable.hh
+++ /dev/null
@@ -1,121 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * SymbolTable.hh
- *
- * Description:
- *
- * $Id$
- *
- * */
-
-#ifndef SYMBOLTABLE_H
-#define SYMBOLTABLE_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/gems_common/Vector.hh"
-
-#include "mem/slicc/symbols/Symbol.hh"
-#include "mem/slicc/symbols/Type.hh"
-#include "mem/slicc/symbols/Var.hh"
-#include "mem/slicc/symbols/Func.hh"
-#include "mem/slicc/symbols/StateMachine.hh"
-
-class SymbolTable;
-
-extern SymbolTable g_sym_table;
-
-class SymbolTable {
-public:
- // Constructors
- SymbolTable();
-
- // Destructor
- ~SymbolTable();
-
- // Public Methods
- void newSym(Symbol* sym_ptr);
- void registerSym(string id, Symbol* sym_ptr);
- Symbol* getSym(string id) const;
-
- // used to cheat-- that is, access components in other machines
- void newMachComponentSym(Symbol* sym_ptr);
- Var* getMachComponentVar(string mach, string ident);
-
- void newCurrentMachine(StateMachine* machine_ptr);
- StateMachine* getStateMachine(string ident) const;
- StateMachine* getStateMachine() const { return getStateMachine("current_machine"); }
- Type* getType(string ident) const;
-
- Var* getVar(string ident) const;
- Func* getFunc(string ident) const;
-
- void pushFrame();
- void popFrame();
-
- Vector<StateMachine*> getStateMachines() const;
-
- void writeCFiles(string path) const;
- void writeHTMLFiles(string path) const;
- void writeMIFFiles(string path) const;
-
- void print(ostream& out) const;
-private:
- // Private Methods
- void registerGlobalSym(string id, Symbol* sym_ptr);
- void writeControllerFactory(string path) const;
-
- // Private copy constructor and assignment operator
- SymbolTable(const SymbolTable& obj);
- SymbolTable& operator=(const SymbolTable& obj);
-
- // Data Members (m_ prefix)
- Vector<Symbol*> m_sym_vec;
- Vector<Map<string, Symbol*> > m_sym_map_vec;
- Map<string, Map<string, Symbol*> > m_machine_component_map_vec;
- int m_depth;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const SymbolTable& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const SymbolTable& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //SYMBOLTABLE_H
diff --git a/src/mem/slicc/symbols/SymbolTable.py b/src/mem/slicc/symbols/SymbolTable.py
new file mode 100644
index 000000000..17d7dfad3
--- /dev/null
+++ b/src/mem/slicc/symbols/SymbolTable.py
@@ -0,0 +1,218 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter
+
+from slicc.generate import html
+from slicc.symbols.StateMachine import StateMachine
+from slicc.symbols.Type import Type
+from slicc.util import Location
+
+class SymbolTable(object):
+ def __init__(self):
+ self.sym_vec = []
+ self.sym_map_vec = [ {} ]
+ self.machine_components = {}
+
+ pairs = {}
+ pairs["enumeration"] = "yes"
+ MachineType = Type(self, "MachineType", Location("init", 0), pairs)
+ self.newSymbol(MachineType)
+
+ pairs = {}
+ pairs["primitive"] = "yes"
+ pairs["external"] = "yes"
+ void = Type(self, "void", Location("init", 0), pairs)
+ self.newSymbol(void)
+
+ def __repr__(self):
+ return "[SymbolTable]" # FIXME
+
+ def newSymbol(self, sym):
+ self.registerSym(str(sym), sym)
+ self.sym_vec.append(sym)
+
+ def registerSym(self, id, sym):
+ # Check for redeclaration (in the current frame only)
+ if id in self.sym_map_vec[-1]:
+ sym.error("Symbol '%s' redeclared in same scope.", id)
+
+ # FIXME - warn on masking of a declaration in a previous frame
+ self.sym_map_vec[-1][id] = sym
+
+ def find(self, ident, types=None):
+ for sym_map in reversed(self.sym_map_vec):
+ try:
+ symbol = sym_map[ident]
+ except KeyError:
+ continue
+
+ if types is not None:
+ assert isinstance(symbol, types)
+
+ return symbol
+
+ return None
+
+ def newMachComponentSym(self, symbol):
+ # used to cheat-- that is, access components in other machines
+ machine = self.find("current_machine", StateMachine)
+ if machine:
+ self.machine_components[str(machine)][str(symbol)] = symbol
+
+ def newCurrentMachine(self, sym):
+ self.registerGlobalSym(str(sym), sym)
+ self.registerSym("current_machine", sym)
+ self.sym_vec.append(sym)
+
+ self.machine_components[str(sym)] = {}
+
+ @property
+ def state_machine(self):
+ return self.find("current_machine", StateMachine)
+
+ def pushFrame(self):
+ self.sym_map_vec.append({})
+
+ def popFrame(self):
+ assert len(self.sym_map_vec) > 0
+ self.sym_map_vec.pop()
+
+ def registerGlobalSym(self, ident, symbol):
+ # Check for redeclaration (global frame only)
+ if ident in self.sym_map_vec[0]:
+ symbol.error("Symbol '%s' redeclared in global scope." % ident)
+
+ self.sym_map_vec[0][ident] = symbol
+
+ def getAllType(self, type):
+ for symbol in self.sym_vec:
+ if isinstance(symbol, type):
+ yield symbol
+
+ def writeCodeFiles(self, path):
+ code = code_formatter()
+ code('''
+/** Auto generated C++ code started by $__file__:$__line__ */
+
+#include "mem/ruby/slicc_interface/RubySlicc_includes.hh"
+''')
+ for symbol in self.sym_vec:
+ if isinstance(symbol, Type) and not symbol.isPrimitive:
+ code('#include "mem/protocol/${{symbol.c_ident}}.hh"')
+
+ code.write(path, "Types.hh")
+
+ for symbol in self.sym_vec:
+ symbol.writeCodeFiles(path)
+
+ self.writeControllerFactory(path)
+
+ def writeControllerFactory(self, path):
+ code = code_formatter()
+
+ code('''
+/** \\file ControllerFactory.hh
+ * Auto generatred C++ code started by $__file__:$__line__
+ */
+
+#ifndef CONTROLLERFACTORY_H
+#define CONTROLLERFACTORY_H
+
+#include <string>
+class Network;
+class AbstractController;
+
+class ControllerFactory {
+ public:
+ static AbstractController *createController(const std::string &controller_type, const std::string &name);
+};
+#endif // CONTROLLERFACTORY_H''')
+ code.write(path, "ControllerFactory.hh")
+
+ code = code_formatter()
+ code('''
+/** \\file ControllerFactory.cc
+ * Auto generatred C++ code started by $__file__:$__line__
+ */
+
+#include "mem/protocol/ControllerFactory.hh"
+#include "mem/ruby/slicc_interface/AbstractController.hh"
+#include "mem/protocol/MachineType.hh"
+''')
+
+ controller_types = []
+ for symbol in self.getAllType(StateMachine):
+ code('#include "mem/protocol/${{symbol.ident}}_Controller.hh"')
+ controller_types.append(symbol.ident)
+
+ code('''
+AbstractController *ControllerFactory::createController(const std::string &controller_type, const std::string &name) {
+''')
+
+ for ct in controller_types:
+ code('''
+ if (controller_type == "$ct")
+ return new ${ct}_Controller(name);
+''')
+
+ code('''
+ assert(0); // invalid controller type
+ return NULL;
+}
+''')
+ code.write(path, "ControllerFactory.cc")
+
+ def writeHTMLFiles(self, path):
+ machines = list(self.getAllType(StateMachine))
+ if len(machines) > 1:
+ name = "%s_table.html" % machines[0].ident
+ else:
+ name = "empty.html"
+
+ code = code_formatter()
+ code('''
+<html>
+<head>
+<title>$path</title>
+</head>
+<frameset rows="*,30">
+ <frame name="Table" src="$name">
+ <frame name="Status" src="empty.html">
+</frameset>
+</html>
+''')
+ code.write(path, "index.html")
+
+ code = code_formatter()
+ code("<HTML></HTML>")
+ code.write(path, "empty.html")
+
+ for symbol in self.sym_vec:
+ symbol.writeHTMLFiles(path)
+
+__all__ = [ "SymbolTable" ]
diff --git a/src/mem/slicc/symbols/Transition.cc b/src/mem/slicc/symbols/Transition.cc
deleted file mode 100644
index d6d348166..000000000
--- a/src/mem/slicc/symbols/Transition.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- * */
-
-#include "mem/slicc/symbols/Transition.hh"
-#include "mem/slicc/symbols/State.hh"
-#include "mem/slicc/symbols/Event.hh"
-#include "mem/slicc/symbols/Action.hh"
-#include "mem/gems_common/util.hh"
-#include "mem/slicc/symbols/Var.hh"
-
-Transition::Transition(string state, string event, string nextState,
- const Vector<string>& actionList,
- const Location& location,
- const Map<string, string>& pairMap)
- : Symbol(state + "|" + event, location, pairMap)
-{
- m_state = state;
- m_event = event;
- m_nextState = nextState;
- m_actionList = actionList;
-
- // Ptrs are undefined at this point
- m_statePtr = NULL;
- m_eventPtr = NULL;
- m_nextStatePtr = NULL;
- m_actionPtrsValid = false;
-}
-
-void Transition::checkIdents(const Vector<State*>& states,
- const Vector<Event*>& events,
- const Vector<Action*>& actions)
-{
- m_statePtr = findIndex(states, m_state);
- m_eventPtr = findIndex(events, m_event);
- m_nextStatePtr = findIndex(states, m_nextState);
-
- for(int i=0; i < m_actionList.size(); i++) {
- Action* action_ptr = findIndex(actions, m_actionList[i]);
- int size = action_ptr->getResources().keys().size();
- for (int j=0; j < size; j++) {
- Var* var_ptr = action_ptr->getResources().keys()[j];
- if (var_ptr->getType()->cIdent() != "DNUCAStopTable") {
- int num = atoi((action_ptr->getResources().lookup(var_ptr)).c_str());
- if (m_resources.exist(var_ptr)) {
- num += atoi((m_resources.lookup(var_ptr)).c_str());
- }
- m_resources.add(var_ptr, int_to_string(num));
- } else {
- m_resources.add(var_ptr, action_ptr->getResources().lookup(var_ptr));
- }
- }
- m_actionPtrs.insertAtBottom(action_ptr);
- }
- m_actionPtrsValid = true;
-}
-
-const string& Transition::getStateShorthand() const
-{
- assert(m_statePtr != NULL);
- return m_statePtr->getShorthand();
-}
-
-const string& Transition::getEventShorthand() const
-{
- assert(m_eventPtr != NULL);
- return m_eventPtr->getShorthand();
-}
-
-const string& Transition::getNextStateShorthand() const
-{
- assert(m_nextStatePtr != NULL);
- return m_nextStatePtr->getShorthand();
-}
-
-string Transition::getActionShorthands() const
-{
- assert(m_actionPtrsValid);
- string str;
- int numActions = m_actionPtrs.size();
- for (int i=0; i<numActions; i++) {
- str += m_actionPtrs[i]->getShorthand();
- }
- return str;
-}
-
-void Transition::print(ostream& out) const
-{
- out << "[Transition: ";
- out << "(" << m_state;
- if (m_statePtr != NULL) {
- out << ":" << *m_statePtr;
- }
- out << ", " << m_event;
- if (m_eventPtr != NULL) {
- out << ":" << *m_eventPtr;
- }
- out << ") -> ";
- out << m_nextState;
- if (m_nextStatePtr != NULL) {
- out << ":" << *m_nextStatePtr;
- }
- out << ", ";
- out << m_actionList;
- out << "]";
-}
-
-Event* Transition::findIndex(const Vector<Event*>& vec, string ident)
-{
- int size = vec.size();
- for(int i=0; i<size; i++) {
- if (ident == vec[i]->getIdent()) {
- return vec[i];
- }
- }
- error("Event not found: " + ident);
- return NULL;
-}
-
-State* Transition::findIndex(const Vector<State*>& vec, string ident)
-{
- int size = vec.size();
- for(int i=0; i<size; i++) {
- if (ident == vec[i]->getIdent()) {
- return vec[i];
- }
- }
- error("State not found: " + ident);
- return NULL;
-}
-
-Action* Transition::findIndex(const Vector<Action*>& vec, string ident)
-{
- int size = vec.size();
- for(int i=0; i<size; i++) {
- if (ident == vec[i]->getIdent()) {
- return vec[i];
- }
- }
- error("Action not found: " + ident);
- return NULL;
-}
-
diff --git a/src/mem/slicc/symbols/Transition.hh b/src/mem/slicc/symbols/Transition.hh
deleted file mode 100644
index 75d6da4e9..000000000
--- a/src/mem/slicc/symbols/Transition.hh
+++ /dev/null
@@ -1,120 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Transition.hh
- *
- * Description:
- *
- * $Id$
- *
- * */
-
-#ifndef TRANSITION_H
-#define TRANSITION_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/gems_common/Vector.hh"
-#include "mem/slicc/symbols/Symbol.hh"
-
-class State;
-class Event;
-class Action;
-class Var;
-
-class Transition : public Symbol {
-public:
- // Constructors
- Transition(string state, string event, string nextState,
- const Vector<string>& actionList,
- const Location& location,
- const Map<string, string>& pairMap);
- // Destructor
- ~Transition() { }
-
- // Public Methods
- State* getStatePtr() const { assert(m_statePtr != NULL); return m_statePtr; }
- Event* getEventPtr() const { assert(m_eventPtr != NULL); return m_eventPtr; }
- State* getNextStatePtr() const { assert(m_nextStatePtr != NULL); return m_nextStatePtr; }
-
- // int getStateIndex() const { assert(m_statePtr != NULL); return m_statePtr->getIndex(); }
- // int getEventIndex() const { assert(m_eventPtr != NULL); return m_eventPtr->getIndex(); }
- // int getNextStateIndex() const { assert(m_nextStatePtr != NULL); return m_nextStatePtr->getIndex(); }
- void checkIdents(const Vector<State*>& states,
- const Vector<Event*>& events,
- const Vector<Action*>& actions);
-
- const string& getStateShorthand() const;
- const string& getEventShorthand() const;
- const string& getNextStateShorthand() const;
- string getActionShorthands() const;
- const Vector<Action*>& getActions() const { assert(m_actionPtrsValid); return m_actionPtrs; }
- const Map<Var*, string>& getResources() const { assert(m_actionPtrsValid); return m_resources; }
-
- void print(ostream& out) const;
-
- // Default copy constructor and assignment operator
- // Transition(const Transition& obj);
- // Transition& operator=(const Transition& obj);
-private:
- // Private Methods
- Event* findIndex(const Vector<Event*>& vec, string ident);
- State* findIndex(const Vector<State*>& vec, string ident);
- Action* findIndex(const Vector<Action*>& vec, string ident);
-
- // Data Members (m_ prefix)
- string m_state;
- string m_event;
- string m_nextState;
-
- State* m_statePtr;
- Event* m_eventPtr;
- State* m_nextStatePtr;
-
- Vector<string> m_actionList;
- Vector<Action*> m_actionPtrs;
- Map<Var*, string> m_resources;
- bool m_actionPtrsValid;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const Transition& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const Transition& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //TRANSITION_H
diff --git a/src/mem/slicc/symbols/Transition.py b/src/mem/slicc/symbols/Transition.py
new file mode 100644
index 000000000..1bf09048a
--- /dev/null
+++ b/src/mem/slicc/symbols/Transition.py
@@ -0,0 +1,61 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.symbols.Symbol import Symbol
+
+class Transition(Symbol):
+ def __init__(self, table, machine, state, event, nextState, actions,
+ location, pairs):
+ ident = "%s|%s" % (state, event)
+ super(Transition, self).__init__(table, ident, location, pairs)
+
+ self.state = machine.states[state]
+ self.event = machine.events[event]
+ self.nextState = machine.states[nextState]
+ self.actions = [ machine.actions[a] for a in actions ]
+ self.resources = {}
+
+ for action in self.actions:
+ for var,value in action.resources.iteritems():
+ if var.type.ident != "DNUCAStopTable":
+ num = int(value)
+ if var in self.resources:
+ num += int(value)
+ self.resources[var] = str(num)
+ else:
+ self.resources[var] = value
+
+ def __repr__(self):
+ return "[Transition: (%r, %r) -> %r, %r]" % \
+ (self.state, self.event, self.nextState, self.actions)
+
+ def getActionShorthands(self):
+ assert self.actions
+
+ return ''.join(a.short for a in self.actions)
+
+__all__ = [ "Transition" ]
diff --git a/src/mem/slicc/symbols/Type.cc b/src/mem/slicc/symbols/Type.cc
deleted file mode 100644
index 5afe53423..000000000
--- a/src/mem/slicc/symbols/Type.cc
+++ /dev/null
@@ -1,779 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Type.cc
- *
- * Description: See Type.hh
- *
- * $Id$
- * */
-
-#include "mem/slicc/symbols/Type.hh"
-#include "mem/slicc/generator/fileio.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/slicc/symbols/StateMachine.hh"
-
-Type::Type(string id, const Location& location,
- const Map<string, string>& pairs,
- StateMachine* machine_ptr)
- : Symbol(id, location, pairs)
-{
- if (machine_ptr == NULL) {
- m_c_id = id;
- } else if (isExternal() || isPrimitive()) {
- if (existPair("external_name")) {
- m_c_id = lookupPair("external_name");
- } else {
- m_c_id = id;
- }
- } else {
- m_c_id = machine_ptr->toString() + "_" + id; // Append with machine name
- }
-
- if(existPair("desc")){
- m_desc = lookupPair("desc");
- } else {
- m_desc = "No description avaliable";
- }
-
- // check for interface that this Type implements
- if(existPair("interface")) {
- string interface = lookupPair("interface");
- if(interface == "Message" || interface == "NetworkMessage") {
- addPair("message", "yes");
- }
- if(interface == "NetworkMessage") {
- addPair("networkmessage", "yes");
- }
- }
-
- // FIXME - all of the following id comparisons are fragile hacks
- if ((getIdent() == "CacheMemory") || (getIdent() == "NewCacheMemory") ||
- (getIdent() == "TLCCacheMemory") || (getIdent() == "DNUCACacheMemory") ||
- (getIdent() == "DNUCABankCacheMemory") || (getIdent() == "L2BankCacheMemory") ||
- (getIdent() == "CompressedCacheMemory") || (getIdent() == "PrefetchCacheMemory")) {
- addPair("cache", "yes");
- }
-
- if ((getIdent() == "TBETable") || (getIdent() == "DNUCATBETable") || (getIdent() == "DNUCAStopTable")) {
- addPair("tbe", "yes");
- }
-
- if ((getIdent() == "NewTBETable")) {
- addPair("newtbe", "yes");
- }
-
- if ((getIdent() == "TimerTable")) {
- addPair("timer", "yes");
- }
-
- if ((getIdent() == "DirectoryMemory")) {
- addPair("dir", "yes");
- }
-
- if ((getIdent() == "PersistentTable")) {
- addPair("persistent", "yes");
- }
-
- if ((getIdent() == "Prefetcher")) {
- addPair("prefetcher", "yes");
- }
-
- if ((getIdent() == "DNUCA_Movement")) {
- addPair("mover", "yes");
- }
-
- if (id == "MachineType") {
- m_isMachineType = true;
- } else {
- m_isMachineType = false;
- }
-}
-
-// Return false on error
-bool Type::dataMemberAdd(string id, Type* type_ptr, Map<string, string>& pairs,
- string* init_code)
-{
- if (dataMemberExist(id)) {
- return false; // Error
- } else {
- m_data_member_map.add(id, type_ptr);
- m_data_member_ident_vec.insertAtBottom(id);
- m_data_member_type_vec.insertAtBottom(type_ptr);
- m_data_member_pairs_vec.insertAtBottom(pairs);
- m_data_member_init_code_vec.insertAtBottom(init_code);
- }
-
- return true;
-}
-
-string Type::methodId(string name,
- const Vector<Type*>& param_type_vec)
-{
- string paramStr = "";
- for (int i = 0; i < param_type_vec.size(); i++) {
- paramStr += "_"+param_type_vec[i]->cIdent();
- }
- return name+paramStr;
-}
-
-bool Type::methodAdd(string name,
- Type* return_type_ptr,
- const Vector<Type*>& param_type_vec)
-{
- string id = methodId(name, param_type_vec);
- if (methodExist(id)) {
- return false; // Error
- } else {
- m_method_return_type_map.add(id, return_type_ptr);
- m_method_param_type_map.add(id, param_type_vec);
- return true;
- }
-}
-
-bool Type::enumAdd(string id, Map<string, string> pairs_map)
-{
- if (enumExist(id)) {
- return false;
- } else {
- m_enum_map.add(id, true);
- m_enum_vec.insertAtBottom(id);
- m_enum_pairs.insertAtBottom(pairs_map);
-
- // Add default
- if (!existPair("default")) {
- addPair("default", cIdent()+"_NUM");
- }
-
- return true;
- }
-}
-
-void Type::writeCFiles(string path)
-{
- if (isExternal()) {
- // Do nothing
- } else if (isEnumeration()) {
- printEnumH(path);
- printEnumC(path);
- } else { // User defined structs and messages
- printTypeH(path);
- printTypeC(path);
- }
-}
-
-void Type::printTypeH(string path) const
-{
- ostringstream out;
- int size = m_data_member_type_vec.size();
- string type_name = cIdent(); // Identifier for the type in C
-
- // Header
- out << "/** \\file " << type_name << ".hh" << endl;
- out << " * " << endl;
- out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << " */" << endl;
- out << endl;
- out << "#ifndef " << type_name << "_H" << endl;
- out << "#define " << type_name << "_H" << endl;
- out << endl;
-
- // Include all of the #includes needed
- out << "#include \"mem/ruby/common/Global.hh\"" << endl;
- out << "#include \"mem/gems_common/Allocator.hh\"" << endl;
- for (int i=0; i < size; i++) {
- Type* type = m_data_member_type_vec[i];
- if (!type->isPrimitive()) {
- out << "#include \"mem/protocol/" << type->cIdent() << ".hh" << "\"" << endl;
- }
- }
- string interface = "";
- if(existPair("interface")) {
- interface = lookupPair("interface");
- out << "#include \"mem/protocol/" << interface << ".hh\"" << endl;
- }
-
- // Class definition
- out << "class " << type_name;
-
- if(interface != "") {
- out << " : public " << interface ;
- }
-
- out << " {" << endl;
- out << "public:" << endl;
-
- // ******** Default constructor ********
-
- out << " " << type_name << "() " << endl;
-
- // Call superclass constructor
- if (interface != "") {
- out << " : " << interface << "()" << endl;
- }
-
- out << " {" << endl;
-
- if(!isGlobal()) {
- for (int i=0; i < size; i++) {
-
- Type* type_ptr = m_data_member_type_vec[i];
- string id = m_data_member_ident_vec[i];
- if (m_data_member_pairs_vec[i].exist("default")) {
- // look for default value
- string default_value = m_data_member_pairs_vec[i].lookup("default");
- out << " m_" << id << " = " << default_value << "; // default for this field " << endl;
- } else if (type_ptr->hasDefault()) {
- // Look for the type default
- string default_value = type_ptr->getDefault();
- out << " m_" << id << " = " << default_value << "; // default value of " << type_ptr->cIdent() << endl;
- } else {
- out << " // m_" << id << " has no default" << endl;
- }
- }
- } // end of if(!isGlobal())
- out << " }" << endl;
-
- // ******** Default destructor ********
- out << " ";
- out << "~" << type_name << "() { };" << endl;
-
- // ******** Full init constructor ********
- if(! isGlobal()) {
- out << " " << type_name << "(";
-
- for (int i=0; i < size; i++) {
- if (i != 0) {
- out << ", ";
- }
- Type* type = m_data_member_type_vec[i];
- string id = m_data_member_ident_vec[i];
- out << "const " << type->cIdent() << "& local_" << id;
- }
-
- if (isMessage()) {
- out << ", const unsigned local_proc_id" << flush;
- }
-
- out << ")" << endl;
-
- // Call superclass constructor
- if (interface != "") {
- out << " : " << interface << "()" << endl;
- }
-
- out << " {" << endl;
- for (int i=0; i < size; i++) {
- Type* type_ptr = m_data_member_type_vec[i];
- string id = m_data_member_ident_vec[i];
- out << " m_" << id << " = local_" << id << ";" << endl;
- if (m_data_member_pairs_vec[i].exist("nextLineCallHack")) {
- string next_line_value = m_data_member_pairs_vec[i].lookup("nextLineCallHack");
- out << " m_" << id << next_line_value << ";" << endl;
- }
- }
- if (isMessage()) {
- out << " proc_id = local_proc_id;" << endl << flush;
- }
- out << " }" << endl;
- } // end of if(!isGlobal())
-
- // create a static factory method
- if (interface != "") {
- out << " static " << interface << "* create() {" << endl;
- out << " return new " << type_name << "(); " << endl;
- out << " }" << endl;
- }
-
- // bobba -
- //******** Partial init constructor ********
- //** Constructor needs only the first n-1 data members for init
- //** HACK to create objects with partially specified data members
- //** Need to get rid of this and use hierarchy instead
-// if(! isGlobal()) {
-// out << " " << type_name << "(";
-
-// for (int i=0; i < size-1; i++) {
-// if (i != 0) {
-// out << ", ";
-// }
-// Type* type = m_data_member_type_vec[i];
-// string id = m_data_member_ident_vec[i];
-// out << "const " << type->cIdent() << "& local_" << id;
-// }
-// out << ")" << endl;
-
-// // Call superclass constructor
-// if (interface != "") {
-// out << " : " << interface << "()" << endl;
-// }
-
-// out << " {" << endl;
-// for (int i=0; i < size-1; i++) {
-// Type* type_ptr = m_data_member_type_vec[i];
-// string id = m_data_member_ident_vec[i];
-// out << " m_" << id << " = local_" << id << ";" << endl;
-// if (m_data_member_pairs_vec[i].exist("nextLineCallHack")) {
-// string next_line_value = m_data_member_pairs_vec[i].lookup("nextLineCallHack");
-// out << " m_" << id << next_line_value << ";" << endl;
-// }
-
-// }
-// out << " }" << endl;
-// } // end of if(!isGlobal())
-
- // ******** Message member functions ********
- // FIXME: those should be moved into slicc file, slicc should support more of
- // the c++ class inheritance
-
- if (isMessage()) {
- out << " Message* clone() const { checkAllocator(); return s_allocator_ptr->allocate(*this); }" << endl;
- out << " void destroy() { checkAllocator(); s_allocator_ptr->deallocate(this); }" << endl;
- out << " static Allocator<" << type_name << ">* s_allocator_ptr;" << endl;
- out << " static void checkAllocator() { if (s_allocator_ptr == NULL) { s_allocator_ptr = new Allocator<" << type_name << ">; }}" << endl;
- }
-
- if(!isGlobal()) {
- // const Get methods for each field
- out << " // Const accessors methods for each field" << endl;
- for (int i=0; i < size; i++) {
- Type* type_ptr = m_data_member_type_vec[i];
- string type = type_ptr->cIdent();
- string id = m_data_member_ident_vec[i];
- out << "/** \\brief Const accessor method for " << id << " field." << endl;
- out << " * \\return " << id << " field" << endl;
- out << " */" << endl;
- out << " const " << type << "& get" << id
- << "() const { return m_" << id << "; }" << endl;
- }
-
- out << endl;
-
- // Non-const Get methods for each field
- out << " // Non const Accessors methods for each field" << endl;
- for (int i=0; i < size; i++) {
- Type* type_ptr = m_data_member_type_vec[i];
- string type = type_ptr->cIdent();
- string id = m_data_member_ident_vec[i];
- out << "/** \\brief Non-const accessor method for " << id << " field." << endl;
- out << " * \\return " << id << " field" << endl;
- out << " */" << endl;
- out << " " << type << "& get" << id
- << "() { return m_" << id << "; }" << endl;
- }
-
- out << endl;
-
- // Set methods for each field
- out << " // Mutator methods for each field" << endl;
- for (int i=0; i < size; i++) {
- Type* type_ptr = m_data_member_type_vec[i];
- string type = type_ptr->cIdent();
- string id = m_data_member_ident_vec[i];
- out << "/** \\brief Mutator method for " << id << " field */" << endl;
- out << " void set" << id << "(const " << type << "& local_"
- << id << ") { m_" << id << " = local_" << id << "; }" << endl;
- }
-
- out << endl;
- } // end of if(!isGlobal())
-
- out << " void print(ostream& out) const;" << endl;
- out << "//private:" << endl;
-
- // Data members for each field
- for (int i=0; i < size; i++) {
- if (!m_data_member_pairs_vec[i].exist("abstract")) {
- out << " ";
- // global structure
- if(isGlobal()) out << "static const ";
-
- Type* type = m_data_member_type_vec[i];
- string id = m_data_member_ident_vec[i];
- out << type->cIdent() << " m_" << id;
-
- // init value
- string* init_code = m_data_member_init_code_vec[i];
- if(init_code) {
- // only global structure can have init value here
- assert(isGlobal());
- out << " = " << *init_code << " ";
- }
- out << ";";
- if (m_data_member_pairs_vec[i].exist("desc")) {
- string desc = m_data_member_pairs_vec[i].lookup("desc");
- out << " /**< " << desc << "*/";
- }
- out << endl;
- }
- }
-
- if (isMessage()) {
- out << " unsigned proc_id;" << endl << flush;
- }
-
- out << "};" << endl; // End class
-
- out << "// Output operator declaration" << endl;
- out << "ostream& operator<<(ostream& out, const " << type_name << "& obj);" << endl;
- out << endl;
- out << "// Output operator definition" << endl;
- out << "extern inline" << endl;
- out << "ostream& operator<<(ostream& out, const " << type_name << "& obj)" << endl;
- out << "{" << endl;
- out << " obj.print(out);" << endl;
- out << " out << flush;" << endl;
- out << " return out;" << endl;
- out << "}" << endl;
- out << endl;
- out << "#endif // " << type_name << "_H" << endl;
-
- // Write it out
- conditionally_write_file(path + type_name + ".hh", out);
-}
-
-void Type::printTypeC(string path) const
-{
- ostringstream out;
- int size = m_data_member_type_vec.size();
- string type_name = cIdent(); // Identifier for the type in C
-
- // Header
- out << "/** \\file " << type_name << ".cc" << endl;
- out << " * " << endl;
- out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << " */" << endl;
- out << endl;
- out << "#include \"mem/protocol/" << type_name << ".hh\"" << endl;
- out << endl;
- if (isMessage()) {
- out << "Allocator<" << type_name << ">* " << type_name << "::s_allocator_ptr = NULL;" << endl;
- }
- out << "/** \\brief Print the state of this object */" << endl;
- out << "void " << type_name << "::print(ostream& out) const" << endl;
- out << "{" << endl;
- out << " out << \"[" << type_name << ": \";" << endl;
-
- // For each field
- for (int i=0; i < size; i++) {
- string id = m_data_member_ident_vec[i];
- out << " out << \"" << id << "=\" << m_" << id << " << \" \";" << endl;
- }
-
- if (isMessage()) {
- out << " out << \"" << "Time" << "=\" << getTime()" << " << \" \";" << endl;
- }
-
- // Trailer
- out << " out << \"]\";" << endl;
- out << "}" << endl;
-
- // Write it out
- conditionally_write_file(path + type_name + ".cc", out);
-}
-
-void Type::printEnumH(string path) const
-{
- ostringstream out;
- int size = m_enum_vec.size();
- string type_name = cIdent(); // Identifier for the type in C
- string type_desc = desc();
-
- // Header
- out << "/** \\file " << type_name << ".hh" << endl;
- out << " * " << endl;
- out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << " */" << endl;
-
- out << "#ifndef " << type_name << "_H" << endl;
- out << "#define " << type_name << "_H" << endl;
- out << endl;
- // Include all of the #includes needed
- out << "#include \"mem/ruby/common/Global.hh\"" << endl;
- out << endl;
-
- // Class definition
- out << "/** \\enum " << type_name << endl;
- out << " * \\brief " << type_desc << endl;
- out << " */" << endl;
- out << "enum " << type_name << " {" << endl;
-
- out << " " << type_name << "_FIRST," << endl;
-
- // For each field
- for(int i = 0; i < size; i++ ) {
- string id = m_enum_vec[i];
- string description;
- if(m_enum_pairs[i].exist("desc")){
- description = m_enum_pairs[i].lookup("desc");
- } else {
- description = "No description avaliable";
- }
- if (i == 0) {
- out << " " << type_name << "_" << id << " = " << type_name << "_FIRST, /**< " << description << " */" << endl;
- }
- else {
- out << " " << type_name << "_" << id << ", /**< " << description << " */" << endl;
- }
- }
- out << " " << type_name << "_NUM" << endl;
- out << "};" << endl;
-
- // Code to convert from a string to the enumeration
- out << type_name << " string_to_" << type_name << "(const string& str);" << endl;
-
- // Code to convert state to a string
- out << "string " << type_name << "_to_string(const " << type_name << "& obj);" << endl;
-
- // Code to increment an enumeration type
- out << type_name << " &operator++( " << type_name << " &e);" << endl;
-
- // MachineType hack used to set the base component id for each Machine
- if (m_isMachineType) {
- out << "int " << type_name << "_base_level(const " << type_name << "& obj);" << endl;
- out << "MachineType " << type_name << "_from_base_level(int);" << endl;
- out << "int " << type_name << "_base_number(const " << type_name << "& obj);" << endl;
- out << "int " << type_name << "_base_count(const " << type_name << "& obj);" << endl;
- // out << "int " << type_name << "_chip_count(const " << type_name << "& obj, int chipID);" << endl;
-
- for(int i = 0; i < size; i++ ) {
- string id = m_enum_vec[i];
- out << "#define MACHINETYPE_" << id << " 1" << endl;
- }
- cout << endl;
- }
-
- // Trailer
- out << "ostream& operator<<(ostream& out, const " << type_name << "& obj);" << endl;
- out << endl;
- out << "#endif // " << type_name << "_H" << endl;
-
- // Write the file
- conditionally_write_file(path + type_name + ".hh", out);
-}
-
-void Type::printEnumC(string path) const
-{
- ostringstream out;
- int size = m_enum_vec.size();
- string type_name = cIdent(); // Identifier for the type in C
-
- // Header
- out << "/** \\file " << type_name << ".hh" << endl;
- out << " * " << endl;
- out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << " */" << endl;
-
- out << endl;
- out << "#include \"mem/protocol/" << type_name << ".hh\"" << endl;
- if (m_isMachineType) {
- out << "#include \"mem/protocol/ControllerFactory.hh\"" << endl;
- for( int i = 0; i<size; i++ ) {
- out << "#include \"mem/protocol/" << m_enum_vec[i] << "_Controller.hh\"" << endl;
- }
- out << endl;
- }
- out << endl;
-
- // Code for output operator
- out << "ostream& operator<<(ostream& out, const " << type_name << "& obj)" << endl;
- out << "{" << endl;
- out << " out << " << type_name << "_to_string(obj);" << endl;
- out << " out << flush;" << endl;
- out << " return out;" << endl;
- out << "}" << endl;
-
- // Code to convert state to a string
- out << endl;
- out << "string " << type_name << "_to_string(const " << type_name << "& obj)" << endl;
- out << "{" << endl;
- out << " switch(obj) {" << endl;
-
- // For each field
- for( int i = 0; i<size; i++ ) {
- out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl;
- out << " return \"" << m_enum_vec[i] << "\";" << endl;
- }
-
- // Trailer
- out << " default:" << endl;
- out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
- out << " return \"\";" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
- // Code to convert from a string to the enumeration
- out << endl;
- out << type_name << " string_to_" << type_name << "(const string& str)" << endl;
- out << "{" << endl;
- out << " if (false) {" << endl;
-
- // For each field
- for( int i = 0; i<size; i++ ) {
- out << " } else if (str == \"" << m_enum_vec[i] << "\") {" << endl;
- out << " return " << type_name << "_" << m_enum_vec[i] << ";" << endl;
- }
-
- out << " } else {" << endl;
- out << " WARN_EXPR(str);" << endl;
- out << " ERROR_MSG(\"Invalid string conversion for type " << type_name << "\");" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
- // Code to increment an enumeration type
- out << endl;
- out << type_name << "& operator++( " << type_name << "& e) {" << endl;
- out << " assert(e < " << type_name << "_NUM);" << endl;
- out << " return e = " << type_name << "(e+1);" << endl;
- out << "}" << endl;
-
- // MachineType hack used to set the base level and number of components for each Machine
- if (m_isMachineType) {
- out << endl;
- out << "/** \\brief returns the base vector index for each machine type to be used by NetDest " << endl;
- out << " * " << endl;
- out << " * \\return the base vector index for each machine type to be used by NetDest" << endl;
- out << " * \\see NetDest.hh" << endl;
- out << " */" << endl;
- out << "int " << type_name << "_base_level(const " << type_name << "& obj)" << endl;
- out << "{" << endl;
- out << " switch(obj) {" << endl;
-
- // For each field
- Vector < string > MachineNames;
- for( int i = 0; i<size; i++ ) {
- out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl;
- out << " return " << MachineNames.size() << ";" << endl;
- MachineNames.insertAtBottom(m_enum_vec[i]);
- }
-
- // total num
- out << " case " << type_name << "_NUM:" << endl;
- out << " return " << MachineNames.size() << ";" << endl;
-
- // Trailer
- out << " default:" << endl;
- out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
- out << " return -1;" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
- out << "/** \\brief returns the machine type for each base vector index used by NetDest" << endl;
- out << " * " << endl;
- out << " * \\return the MachineTYpe" << endl;
- out << " */" << endl;
- out << "MachineType " << type_name << "_from_base_level(int type)" << endl;
- out << "{" << endl;
- out << " switch(type) {" << endl;
-
- // For each field
- MachineNames.clear();
- for( int i = 0; i<size; i++ ) {
- out << " case " << MachineNames.size() << ":" << endl;
- out << " return " << type_name << "_" << m_enum_vec[i] << ";" << endl;
- MachineNames.insertAtBottom(m_enum_vec[i]);
- }
-
- // Trailer
- out << " default:" << endl;
- out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
- out << " return MachineType_NUM;" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
-
- out << endl;
- out << "/** \\brief The return value indicates the number of components created" << endl;
- out << " * before a particular machine's components" << endl;
- out << " * " << endl;
- out << " * \\return the base number of components for each machine" << endl;
- out << " */" << endl;
- out << "int " << type_name << "_base_number(const " << type_name << "& obj)" << endl;
- out << "{" << endl;
- out << " switch(obj) {" << endl;
-
- // For each field
- MachineNames.clear();
- for( int i = 0; i<size; i++ ) {
- out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl;
- out << " return 0";
- for ( int m = 0; m<MachineNames.size(); m++) {
- out << "+ " << MachineNames[m] << "_Controller::getNumControllers()";
- }
- out << ";" << endl;
- MachineNames.insertAtBottom(m_enum_vec[i]);
- }
-
- // total num
- out << " case " << type_name << "_NUM:" << endl;
- out << " return 0";
- for ( int m = 0; m<MachineNames.size(); m++) {
- out << "+ " << MachineNames[m] << "_Controller::getNumControllers()";
- }
- out << ";" << endl;
-
- // Trailer
- out << " default:" << endl;
- out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
- out << " return -1;" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
-
- out << endl;
- out << "/** \\brief returns the total number of components for each machine" << endl;
- out << " * \\return the total number of components for each machine" << endl;
- out << " */" << endl;
- out << "int " << type_name << "_base_count(const " << type_name << "& obj)" << endl;
- out << "{" << endl;
- out << " switch(obj) {" << endl;
-
- // For each field
- for( int i = 0; i<size; i++ ) {
- out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl;
- out << " return " << m_enum_vec[i] << "_Controller::getNumControllers();" << endl;
- }
-
- // total num
- out << " case " << type_name << "_NUM:" << endl;
- // Trailer
- out << " default:" << endl;
- out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
- out << " return -1;" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
- out << endl;
-
- }
-
- // Write the file
- conditionally_write_file(path + type_name + ".cc", out);
-}
diff --git a/src/mem/slicc/symbols/Type.hh b/src/mem/slicc/symbols/Type.hh
deleted file mode 100644
index 07d661d3c..000000000
--- a/src/mem/slicc/symbols/Type.hh
+++ /dev/null
@@ -1,155 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Type.hh
- *
- * Description:
- *
- * $Id$
- *
- * */
-
-#ifndef TYPE_H
-#define TYPE_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/slicc/symbols/Symbol.hh"
-
-class StateMachine;
-
-class Type : public Symbol {
-public:
- // Constructors
- Type(string id, const Location& location,
- const Map<string, string>& pairs,
- StateMachine* machine_ptr = NULL);
-
- // Destructor
- ~Type() {}
-
- // Public Methods
- string cIdent() const { return m_c_id; }
- string desc() const { return m_desc; }
-
- bool isPrimitive() const { return existPair("primitive"); }
- bool isNetworkMessage() const { return existPair("networkmessage"); }
- bool isMessage() const { return existPair("message"); }
- bool isBuffer() const { return existPair("buffer"); }
- bool isInPort() const { return existPair("inport"); }
- bool isOutPort() const { return existPair("outport"); }
- bool isEnumeration() const { return existPair("enumeration"); }
- bool isExternal() const { return existPair("external"); }
- bool isGlobal() const { return existPair("global"); }
- bool isInterface() const { return existPair("interface"); }
-
- // The data members of this type - only valid for messages and SLICC
- // declared structures
- // Return false on error
- bool dataMemberAdd(string id, Type* type_ptr, Map<string, string>& pairs,
- string* init_code);
- bool dataMemberExist(string id) const { return m_data_member_map.exist(id); }
- Type* dataMemberType(string id) const { return m_data_member_map.lookup(id); }
-
- // The methods of this type - only valid for external types
- // Return false on error
- bool methodAdd(string name, Type* return_type_ptr, const Vector<Type*>& param_type_vec);
- bool methodExist(string id) const { return m_method_return_type_map.exist(id); }
-
- string methodId(string name, const Vector<Type*>& param_type_vec);
- Type* methodReturnType(string id) const { return m_method_return_type_map.lookup(id); }
- const Vector<Type*>& methodParamType(string id) const { return m_method_param_type_map.lookup(id); }
-
- // The enumeration idents of this type - only valid for enums
- // Return false on error
- bool enumAdd(string id, Map<string, string> pairs);
- bool enumExist(string id) const { return m_enum_map.exist(id); }
-
- // Write the C output files
- void writeCFiles(string path) ;
-
- bool hasDefault() const { return existPair("default"); }
- string getDefault() const { return lookupPair("default"); }
-
- void print(ostream& out) const {}
-private:
- // Private Methods
-
- void printTypeH(string path) const;
- void printTypeC(string path) const;
- void printEnumC(string path) const;
- void printEnumH(string path) const;
-
- // Private copy constructor and assignment operator
- Type(const Type& obj);
- Type& operator=(const Type& obj);
-
- // Data Members (m_ prefix)
- string m_c_id;
- string m_desc;
-
- // Data Members
- Map<string, Type*> m_data_member_map;
- Vector<string> m_data_member_ident_vec;
- Vector<Type*> m_data_member_type_vec;
- Vector<Map<string, string> > m_data_member_pairs_vec;
- Vector<string*> m_data_member_init_code_vec;
- // Needs pairs here
-
- // Methods
- Map<string, Type*> m_method_return_type_map;
- Map<string, Vector<Type*> > m_method_param_type_map;
- // Needs pairs here
-
- // Enum
- Map<string, bool> m_enum_map;
- Vector<string> m_enum_vec;
- Vector< Map < string, string > > m_enum_pairs;
-
- // MachineType Hack
- bool m_isMachineType;
-
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const Type& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const Type& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //TYPE_H
diff --git a/src/mem/slicc/symbols/Type.py b/src/mem/slicc/symbols/Type.py
new file mode 100644
index 000000000..2541296dc
--- /dev/null
+++ b/src/mem/slicc/symbols/Type.py
@@ -0,0 +1,650 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter, orderdict
+
+from slicc.util import PairContainer
+from slicc.symbols.Symbol import Symbol
+
+class DataMember(PairContainer):
+ def __init__(self, ident, type, pairs, init_code):
+ super(DataMember, self).__init__(pairs)
+ self.ident = ident
+ self.type = type
+ self.init_code = init_code
+
+class Enumeration(PairContainer):
+ def __init__(self, ident, pairs):
+ super(Enumeration, self).__init__(pairs)
+ self.ident = ident
+
+class Method(object):
+ def __init__(self, return_type, param_types):
+ self.return_type = return_type
+ self.param_types = param_types
+
+class Type(Symbol):
+ def __init__(self, table, ident, location, pairs, machine=None):
+ super(Type, self).__init__(table, ident, location, pairs)
+ self.c_ident = ident
+ if machine:
+ if self.isExternal or self.isPrimitive:
+ if "external_name" in self:
+ self.c_ident = self["external_name"]
+ else:
+ # Append with machine name
+ self.c_ident = "%s_%s" % (machine, ident)
+
+ self.pairs.setdefault("desc", "No description avaliable")
+
+ # check for interface that this Type implements
+ if "interface" in self:
+ interface = self["interface"]
+ if interface in ("Message", "NetworkMessage"):
+ self["message"] = "yes"
+ if interface == "NetworkMessage":
+ self["networkmessage"] = "yes"
+
+ # FIXME - all of the following id comparisons are fragile hacks
+ if self.ident in ("CacheMemory", "NewCacheMemory",
+ "TLCCacheMemory", "DNUCACacheMemory",
+ "DNUCABankCacheMemory", "L2BankCacheMemory",
+ "CompressedCacheMemory", "PrefetchCacheMemory"):
+ self["cache"] = "yes"
+
+ if self.ident in ("TBETable", "DNUCATBETable", "DNUCAStopTable"):
+ self["tbe"] = "yes"
+
+ if self.ident == "NewTBETable":
+ self["newtbe"] = "yes"
+
+ if self.ident == "TimerTable":
+ self["timer"] = "yes"
+
+ if self.ident == "DirectoryMemory":
+ self["dir"] = "yes"
+
+ if self.ident == "PersistentTable":
+ self["persistent"] = "yes"
+
+ if self.ident == "Prefetcher":
+ self["prefetcher"] = "yes"
+
+ if self.ident == "DNUCA_Movement":
+ self["mover"] = "yes"
+
+ self.isMachineType = (ident == "MachineType")
+
+ self.data_members = orderdict()
+
+ # Methods
+ self.methods = {}
+
+ # Enums
+ self.enums = orderdict()
+
+ @property
+ def isPrimitive(self):
+ return "primitive" in self
+ @property
+ def isNetworkMessage(self):
+ return "networkmessage" in self
+ @property
+ def isMessage(self):
+ return "message" in self
+ @property
+ def isBuffer(self):
+ return "buffer" in self
+ @property
+ def isInPort(self):
+ return "inport" in self
+ @property
+ def isOutPort(self):
+ return "outport" in self
+ @property
+ def isEnumeration(self):
+ return "enumeration" in self
+ @property
+ def isExternal(self):
+ return "external" in self
+ @property
+ def isGlobal(self):
+ return "global" in self
+ @property
+ def isInterface(self):
+ return "interface" in self
+
+ # Return false on error
+ def dataMemberAdd(self, ident, type, pairs, init_code):
+ if ident in self.data_members:
+ return False
+
+ member = DataMember(ident, type, pairs, init_code)
+ self.data_members[ident] = member
+
+ return True
+
+ def dataMemberType(self, ident):
+ return self.data_members[ident].type
+
+ def methodId(self, name, param_type_vec):
+ return '_'.join([name] + [ pt.c_ident for pt in param_type_vec ])
+
+ def methodAdd(self, name, return_type, param_type_vec):
+ ident = self.methodId(name, param_type_vec)
+ if ident in self.methods:
+ return False
+
+ self.methods[ident] = Method(return_type, param_type_vec)
+ return True
+
+ def enumAdd(self, ident, pairs):
+ if ident in self.enums:
+ return False
+
+ self.enums[ident] = Enumeration(ident, pairs)
+
+ # Add default
+ if "default" not in self:
+ self["default"] = "%s_NUM" % self.c_ident
+
+ return True
+
+ def writeCodeFiles(self, path):
+ if self.isExternal:
+ # Do nothing
+ pass
+ elif self.isEnumeration:
+ self.printEnumHH(path)
+ self.printEnumCC(path)
+ else:
+ # User defined structs and messages
+ self.printTypeHH(path)
+ self.printTypeCC(path)
+
+ def printTypeHH(self, path):
+ code = code_formatter()
+ code('''
+/** \\file ${{self.c_ident}}.hh
+ *
+ *
+ * Auto generated C++ code started by $__file__:$__line__
+ */
+
+#ifndef ${{self.c_ident}}_H
+#define ${{self.c_ident}}_H
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/gems_common/Allocator.hh"
+''')
+
+ for dm in self.data_members.values():
+ if not dm.type.isPrimitive:
+ code('#include "mem/protocol/$0.hh"', dm.type.c_ident)
+
+ parent = ""
+ if "interface" in self:
+ code('#include "mem/protocol/$0.hh"', self["interface"])
+ parent = " : public %s" % self["interface"]
+
+ code('''
+$klass ${{self.c_ident}}$parent {
+ public:
+ ${{self.c_ident}}()
+''', klass="class")
+
+ # Call superclass constructor
+ if "interface" in self:
+ code(' : ${{self["interface"]}}()')
+
+ code.indent()
+ code("{")
+ if not self.isGlobal:
+ code.indent()
+ for dm in self.data_members.values():
+ ident = dm.ident
+ if "default" in dm:
+ # look for default value
+ code('m_$ident = ${{dm["default"]}}; // default for this field')
+ elif "default" in dm.type:
+ # Look for the type default
+ tid = dm.type.c_ident
+ code('m_$ident = ${{dm.type["default"]}}; // default value of $tid')
+ else:
+ code('// m_$ident has no default')
+ code.dedent()
+ code('}')
+
+ # ******** Default destructor ********
+ code('~${{self.c_ident}}() { };')
+
+ # ******** Full init constructor ********
+ if not self.isGlobal:
+ params = [ 'const %s& local_%s' % (dm.type.c_ident, dm.ident) \
+ for dm in self.data_members.itervalues() ]
+
+ if self.isMessage:
+ params.append('const unsigned local_proc_id')
+
+ params = ', '.join(params)
+ code('${{self.c_ident}}($params)')
+
+ # Call superclass constructor
+ if "interface" in self:
+ code(' : ${{self["interface"]}}()')
+
+ code('{')
+ code.indent()
+ for dm in self.data_members.values():
+ code('m_${{dm.ident}} = local_${{dm.ident}};')
+ if "nextLineCallHack" in dm:
+ code('m_${{dm.ident}}${{dm["nextLineCallHack"]}};')
+
+ if self.isMessage:
+ code('proc_id = local_proc_id;')
+
+ code.dedent()
+ code('}')
+
+ # create a static factory method
+ if "interface" in self:
+ code('''
+static ${{self["interface"]}}* create() {
+ return new ${{self.c_ident}}();
+}
+''')
+
+ # ******** Message member functions ********
+ # FIXME: those should be moved into slicc file, slicc should
+ # support more of the c++ class inheritance
+
+ if self.isMessage:
+ code('''
+Message* clone() const { checkAllocator(); return s_allocator_ptr->allocate(*this); }
+void destroy() { checkAllocator(); s_allocator_ptr->deallocate(this); }
+static Allocator<${{self.c_ident}}>* s_allocator_ptr;
+static void checkAllocator() { if (s_allocator_ptr == NULL) { s_allocator_ptr = new Allocator<${{self.c_ident}}>; }}
+''')
+
+ if not self.isGlobal:
+ # const Get methods for each field
+ code('// Const accessors methods for each field')
+ for dm in self.data_members.values():
+ code('''
+/** \\brief Const accessor method for ${{dm.ident}} field.
+ * \\return ${{dm.ident}} field
+ */
+const ${{dm.type.c_ident}}& get${{dm.ident}}() const { return m_${{dm.ident}}; }
+''')
+
+ # Non-const Get methods for each field
+ code('// Non const Accessors methods for each field')
+ for dm in self.data_members.values():
+ code('''
+/** \\brief Non-const accessor method for ${{dm.ident}} field.
+ * \\return ${{dm.ident}} field
+ */
+${{dm.type.c_ident}}& get${{dm.ident}}() { return m_${{dm.ident}}; }
+''')
+
+ #Set methods for each field
+ code('// Mutator methods for each field')
+ for dm in self.data_members.values():
+ code('''
+/** \\brief Mutator method for ${{dm.ident}} field */
+void set${{dm.ident}}(const ${{dm.type.c_ident}}& local_${{dm.ident}}) { m_${{dm.ident}} = local_${{dm.ident}}; }
+''')
+
+ code('void print(ostream& out) const;')
+ code.dedent()
+ code(' //private:')
+ code.indent()
+
+ # Data members for each field
+ for dm in self.data_members.values():
+ if "abstract" not in dm:
+ const = ""
+ init = ""
+
+ # global structure
+ if self.isGlobal:
+ const = "static const "
+
+ # init value
+ if dm.init_code:
+ # only global structure can have init value here
+ assert self.isGlobal
+ init = " = %s" % (dm.init_code)
+
+ desc = ""
+ if "desc" in dm:
+ desc = '/**< %s */' % dm["desc"]
+
+ code('$const${{dm.type.c_ident}} m_${{dm.ident}}$init; $desc')
+
+ if self.isMessage:
+ code('unsigned proc_id;')
+
+ code.dedent()
+ code('};')
+
+ code('''
+// Output operator declaration
+ostream& operator<<(ostream& out, const ${{self.c_ident}}& obj);
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const ${{self.c_ident}}& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif // ${{self.c_ident}}_H
+''')
+
+ code.write(path, "%s.hh" % self.c_ident)
+
+ def printTypeCC(self, path):
+ code = code_formatter()
+
+ code('''
+/** \\file ${{self.c_ident}}.cc
+ *
+ * Auto generated C++ code started by $__file__:$__line__
+ */
+
+#include "mem/protocol/${{self.c_ident}}.hh"
+''')
+
+ if self.isMessage:
+ code('Allocator<${{self.c_ident}}>* ${{self.c_ident}}::s_allocator_ptr = NULL;')
+ code('''
+/** \\brief Print the state of this object */
+void ${{self.c_ident}}::print(ostream& out) const
+{
+ out << "[${{self.c_ident}}: ";
+''')
+
+ # For each field
+ code.indent()
+ for dm in self.data_members.values():
+ code('out << "${{dm.ident}} = " << m_${{dm.ident}} << " ";''')
+
+ if self.isMessage:
+ code('out << "Time = " << getTime() << " ";')
+ code.dedent()
+
+ # Trailer
+ code('''
+ out << "]";
+}''')
+
+ code.write(path, "%s.cc" % self.c_ident)
+
+ def printEnumHH(self, path):
+ code = code_formatter()
+ code('''
+/** \\file ${{self.c_ident}}.hh
+ *
+ * Auto generated C++ code started by $__file__:$__line__
+ */
+#ifndef ${{self.c_ident}}_H
+#define ${{self.c_ident}}_H
+
+#include "mem/ruby/common/Global.hh"
+
+/** \\enum ${{self.c_ident}}
+ * \\brief ${{self.desc}}
+ */
+enum ${{self.c_ident}} {
+ ${{self.c_ident}}_FIRST,
+''')
+
+ code.indent()
+ # For each field
+ for i,(ident,enum) in enumerate(self.enums.iteritems()):
+ desc = enum.get("desc", "No description avaliable")
+ init = ' = %s_FIRST' % self.c_ident if i == 0 else ''
+
+ code('${{self.c_ident}}_${{enum.ident}}$init, /**< $desc */')
+ code.dedent()
+ code('''
+ ${{self.c_ident}}_NUM
+};
+${{self.c_ident}} string_to_${{self.c_ident}}(const string& str);
+string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj);
+${{self.c_ident}} &operator++(${{self.c_ident}} &e);
+''')
+
+ # MachineType hack used to set the base component id for each Machine
+ if self.isMachineType:
+ code('''
+int ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj);
+MachineType ${{self.c_ident}}_from_base_level(int);
+int ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj);
+int ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj);
+''')
+
+ for enum in self.enums.itervalues():
+ code('#define MACHINETYPE_${{enum.ident}} 1')
+
+ # Trailer
+ code('''
+ostream& operator<<(ostream& out, const ${{self.c_ident}}& obj);
+
+#endif // ${{self.c_ident}}_H
+''')
+
+ code.write(path, "%s.hh" % self.c_ident)
+
+ def printEnumCC(self, path):
+ code = code_formatter()
+ code('''
+/** \\file ${{self.c_ident}}.hh
+ *
+ * Auto generated C++ code started by $__file__:$__line__
+ */
+
+#include "mem/protocol/${{self.c_ident}}.hh"
+
+''')
+
+ if self.isMachineType:
+ code('#include "mem/protocol/ControllerFactory.hh"')
+ for enum in self.enums.itervalues():
+ code('#include "mem/protocol/${{enum.ident}}_Controller.hh"')
+
+ code('''
+ostream& operator<<(ostream& out, const ${{self.c_ident}}& obj)
+{
+ out << ${{self.c_ident}}_to_string(obj);
+ out << flush;
+ return out;
+}
+
+string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj)
+{
+ switch(obj) {
+''')
+
+ # For each field
+ code.indent()
+ for enum in self.enums.itervalues():
+ code(' case ${{self.c_ident}}_${{enum.ident}}:')
+ code(' return "${{enum.ident}}";')
+ code.dedent()
+
+ # Trailer
+ code('''
+ default:
+ ERROR_MSG("Invalid range for type ${{self.c_ident}}");
+ return "";
+ }
+}
+
+${{self.c_ident}} string_to_${{self.c_ident}}(const string& str)
+{
+''')
+
+ # For each field
+ code.indent()
+ code("if (false) {")
+ start = "} else "
+ for enum in self.enums.itervalues():
+ code('${start}if (str == "${{enum.ident}}") {')
+ code(' return ${{self.c_ident}}_${{enum.ident}};')
+ code.dedent()
+
+ code('''
+ } else {
+ WARN_EXPR(str);
+ ERROR_MSG("Invalid string conversion for type ${{self.c_ident}}");
+ }
+}
+
+${{self.c_ident}}& operator++(${{self.c_ident}}& e) {
+ assert(e < ${{self.c_ident}}_NUM);
+ return e = ${{self.c_ident}}(e+1);
+}
+''')
+
+ # MachineType hack used to set the base level and number of
+ # components for each Machine
+ if self.isMachineType:
+ code('''
+/** \\brief returns the base vector index for each machine type to be used by NetDest
+ *
+ * \\return the base vector index for each machine type to be used by NetDest
+ * \\see NetDest.hh
+ */
+int ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj)
+{
+ switch(obj) {
+''')
+
+ # For each field
+ code.indent()
+ for i,enum in enumerate(self.enums.itervalues()):
+ code(' case ${{self.c_ident}}_${{enum.ident}}:')
+ code(' return $i;')
+ code.dedent()
+
+ # total num
+ code('''
+ case ${{self.c_ident}}_NUM:
+ return ${{len(self.enums)}};
+
+ default:
+ ERROR_MSG("Invalid range for type ${{self.c_ident}}");
+ return -1;
+ }
+}
+
+/** \\brief returns the machine type for each base vector index used by NetDest
+ *
+ * \\return the MachineTYpe
+ */
+MachineType ${{self.c_ident}}_from_base_level(int type)
+{
+ switch(type) {
+''')
+
+ # For each field
+ code.indent()
+ for i,enum in enumerate(self.enums.itervalues()):
+ code(' case $i:')
+ code(' return ${{self.c_ident}}_${{enum.ident}};')
+ code.dedent()
+
+ # Trailer
+ code('''
+ default:
+ ERROR_MSG("Invalid range for type ${{self.c_ident}}");
+ return MachineType_NUM;
+ }
+}
+
+/** \\brief The return value indicates the number of components created
+ * before a particular machine\'s components
+ *
+ * \\return the base number of components for each machine
+ */
+int ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj)
+{
+ int base = 0;
+ switch(obj) {
+''')
+
+ # For each field
+ code.indent()
+ code(' case ${{self.c_ident}}_NUM:')
+ for enum in reversed(self.enums.values()):
+ code(' base += ${{enum.ident}}_Controller::getNumControllers();')
+ code(' case ${{self.c_ident}}_${{enum.ident}}:')
+ code(' break;')
+ code.dedent()
+
+ code('''
+ default:
+ ERROR_MSG("Invalid range for type ${{self.c_ident}}");
+ return -1;
+ }
+
+ return base;
+}
+
+/** \\brief returns the total number of components for each machine
+ * \\return the total number of components for each machine
+ */
+int ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj)
+{
+ switch(obj) {
+''')
+
+ # For each field
+ for enum in self.enums.itervalues():
+ code('''
+ case ${{self.c_ident}}_${{enum.ident}}:
+ return ${{enum.ident}}_Controller::getNumControllers();
+''')
+
+ # total num
+ code('''
+ case ${{self.c_ident}}_NUM:
+ default:
+ ERROR_MSG("Invalid range for type ${{self.c_ident}}");
+ return -1;
+ }
+}
+''')
+
+ # Write the file
+ code.write(path, "%s.cc" % self.c_ident)
+
+__all__ = [ "Type" ]
diff --git a/src/mem/slicc/symbols/Var.cc b/src/mem/slicc/symbols/Var.cc
deleted file mode 100644
index a6e8dfd55..000000000
--- a/src/mem/slicc/symbols/Var.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- * */
-
-#include "mem/slicc/symbols/Var.hh"
-#include "mem/slicc/symbols/StateMachine.hh"
-
-Var::Var(string id, const Location& location,
- Type* type_ptr, string code,
- const Map<string, string>& pairs,
- StateMachine* machine_ptr) : Symbol(id, location, pairs)
-{
- if (machine_ptr == NULL) {
- m_c_id = id;
- } else {
- m_c_id = machine_ptr->toString() + "_" + id; // Append with machine name
- }
-
- m_machine_ptr = machine_ptr;
- m_type_ptr = type_ptr;
- m_code = code;
-}
-
-void Var::print(ostream& out) const
-{
- out << "[Var id: " << m_c_id << "]" << endl;
-}
diff --git a/src/mem/slicc/symbols/Var.hh b/src/mem/slicc/symbols/Var.hh
deleted file mode 100644
index 4cb504296..000000000
--- a/src/mem/slicc/symbols/Var.hh
+++ /dev/null
@@ -1,98 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Var.hh
- *
- * Description:
- *
- * $Id$
- *
- * */
-
-#ifndef VAR_H
-#define VAR_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/symbols/Symbol.hh"
-#include "mem/slicc/symbols/Type.hh"
-
-class StateMachine;
-
-class Var : public Symbol {
-public:
- // Constructors
- Var(string id, const Location& location,
- Type* type_ptr, string code,
- const Map<string, string>& pairs,
- StateMachine* machine_ptr = NULL);
-
- // Var(string id, const Location& location,
- // Type* type_ptr, string code) : Symbol(id, location) { m_type_ptr = type_ptr; m_code = code; }
-
- // Destructor
- ~Var() {}
-
- // Public Methods
- string cIdent() const { return m_c_id; }
- void writeCFiles(string path) {}
- string getCode() const { return m_code; }
- Type* getType() const { return m_type_ptr; }
- StateMachine* getMachine() const { return m_machine_ptr; }
-
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- Var(const Var& obj);
- Var& operator=(const Var& obj);
-
- // Data Members (m_ prefix)
- string m_c_id;
- Type* m_type_ptr;
- string m_code;
- StateMachine* m_machine_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const Var& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const Var& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //VAR_H
diff --git a/src/mem/slicc/symbols/Var.py b/src/mem/slicc/symbols/Var.py
new file mode 100644
index 000000000..87a101f65
--- /dev/null
+++ b/src/mem/slicc/symbols/Var.py
@@ -0,0 +1,50 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.symbols.Symbol import Symbol
+
+class Var(Symbol):
+ def __init__(self, symtab, ident, location, type, code, pairs,
+ machine=None):
+ super(Var, self).__init__(symtab, ident, location, pairs)
+
+ if machine:
+ self.c_ident = "%s_%s" % (machine, ident)
+ else:
+ self.c_ident = ident
+
+ self.machine = machine
+ self.type = type
+ self.code = code
+
+ def __repr__(self):
+ return "[Var id: %s]" % (self.c_ident)
+
+ def writeCodeFiles(self, path):
+ pass
+
+__all__ = [ "Var" ]
diff --git a/src/mem/slicc/symbols/__init__.py b/src/mem/slicc/symbols/__init__.py
new file mode 100644
index 000000000..43388a5fe
--- /dev/null
+++ b/src/mem/slicc/symbols/__init__.py
@@ -0,0 +1,38 @@
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+from slicc.symbols.Action import Action
+from slicc.symbols.Event import Event
+from slicc.symbols.Func import Func
+from slicc.symbols.State import State
+from slicc.symbols.StateMachine import StateMachine
+from slicc.symbols.Symbol import Symbol
+from slicc.symbols.SymbolTable import SymbolTable
+from slicc.symbols.Transition import Transition
+from slicc.symbols.Type import Type
+from slicc.symbols.Var import Var