diff options
author | Nathan Binkert <nate@binkert.org> | 2009-07-06 15:49:47 -0700 |
---|---|---|
committer | Nathan Binkert <nate@binkert.org> | 2009-07-06 15:49:47 -0700 |
commit | 92de70b69aaf3f399a855057b556ed198139e5d8 (patch) | |
tree | f8e7d0d494df8810cc960be4c52d8b555471f157 /src/mem/slicc | |
parent | 05f6a4a6b92370162da17ef5cccb5a7e3ba508e5 (diff) | |
download | gem5-92de70b69aaf3f399a855057b556ed198139e5d8.tar.xz |
ruby: Import the latest ruby changes from gems.
This was done with an automated process, so there could be things that were
done in this tree in the past that didn't make it. One known regression
is that atomic memory operations do not seem to work properly anymore.
Diffstat (limited to 'src/mem/slicc')
-rw-r--r-- | src/mem/slicc/ast/ASTs.hh | 1 | ||||
-rw-r--r-- | src/mem/slicc/ast/EnqueueStatementAST.cc | 2 | ||||
-rw-r--r-- | src/mem/slicc/ast/MachineAST.cc | 6 | ||||
-rw-r--r-- | src/mem/slicc/ast/MachineAST.hh | 5 | ||||
-rw-r--r-- | src/mem/slicc/ast/MethodCallExprAST.cc | 26 | ||||
-rw-r--r-- | src/mem/slicc/ast/NewExprAST.cc | 9 | ||||
-rw-r--r-- | src/mem/slicc/ast/NewExprAST.hh | 20 | ||||
-rw-r--r-- | src/mem/slicc/ast/ObjDeclAST.cc | 29 | ||||
-rw-r--r-- | src/mem/slicc/parser/lexer.ll | 9 | ||||
-rw-r--r-- | src/mem/slicc/parser/parser.yy | 28 | ||||
-rw-r--r-- | src/mem/slicc/symbols/Func.cc | 5 | ||||
-rw-r--r-- | src/mem/slicc/symbols/Func.hh | 2 | ||||
-rw-r--r-- | src/mem/slicc/symbols/StateMachine.cc | 439 | ||||
-rw-r--r-- | src/mem/slicc/symbols/StateMachine.hh | 34 | ||||
-rw-r--r-- | src/mem/slicc/symbols/Symbol.hh | 4 | ||||
-rw-r--r-- | src/mem/slicc/symbols/SymbolTable.cc | 717 | ||||
-rw-r--r-- | src/mem/slicc/symbols/SymbolTable.hh | 2 | ||||
-rw-r--r-- | src/mem/slicc/symbols/Type.cc | 94 | ||||
-rw-r--r-- | src/mem/slicc/symbols/Type.hh | 3 | ||||
-rw-r--r-- | src/mem/slicc/symbols/Var.hh | 2 |
20 files changed, 646 insertions, 791 deletions
diff --git a/src/mem/slicc/ast/ASTs.hh b/src/mem/slicc/ast/ASTs.hh index d0ed5698f..3363fbb09 100644 --- a/src/mem/slicc/ast/ASTs.hh +++ b/src/mem/slicc/ast/ASTs.hh @@ -72,6 +72,7 @@ #include "mem/slicc/ast/InfixOperatorExprAST.hh" #include "mem/slicc/ast/FuncCallExprAST.hh" #include "mem/slicc/ast/MethodCallExprAST.hh" +#include "mem/slicc/ast/NewExprAST.hh" #include "mem/slicc/ast/ChipComponentAccessAST.hh" diff --git a/src/mem/slicc/ast/EnqueueStatementAST.cc b/src/mem/slicc/ast/EnqueueStatementAST.cc index e323e67ac..744dfe1eb 100644 --- a/src/mem/slicc/ast/EnqueueStatementAST.cc +++ b/src/mem/slicc/ast/EnqueueStatementAST.cc @@ -77,7 +77,7 @@ void EnqueueStatementAST::generate(string& code, Type* return_type_ptr) const code += ".enqueue(out_msg"; if (getPairs().exist("latency")) { - code += ", " + getPairs().lookup("latency"); + code += ", RubyConfig::get" + getPairs().lookup("latency") + "()"; } code += ");\n"; diff --git a/src/mem/slicc/ast/MachineAST.cc b/src/mem/slicc/ast/MachineAST.cc index 8c2f647be..2096db591 100644 --- a/src/mem/slicc/ast/MachineAST.cc +++ b/src/mem/slicc/ast/MachineAST.cc @@ -41,13 +41,17 @@ MachineAST::MachineAST(string* ident_ptr, PairListAST* pairs_ptr, + Vector<TypeFieldAST*>* config_params_ptr, + std::vector<std::string*>* latency_vector, DeclListAST* decl_list_ptr) : DeclAST(pairs_ptr) { m_ident_ptr = ident_ptr; m_pairs_ptr = pairs_ptr; + m_config_params_ptr = config_params_ptr; m_decl_list_ptr = decl_list_ptr; + m_latency_vector = latency_vector; } MachineAST::~MachineAST() @@ -65,7 +69,7 @@ void MachineAST::generate() g_sym_table.pushFrame(); // Create a new machine - machine_ptr = new StateMachine(*m_ident_ptr, getLocation(), getPairs()); + machine_ptr = new StateMachine(*m_ident_ptr, getLocation(), getPairs(), m_latency_vector); g_sym_table.newCurrentMachine(machine_ptr); // Generate code for all the internal decls diff --git a/src/mem/slicc/ast/MachineAST.hh b/src/mem/slicc/ast/MachineAST.hh index 037803db5..8f83e4cfe 100644 --- a/src/mem/slicc/ast/MachineAST.hh +++ b/src/mem/slicc/ast/MachineAST.hh @@ -42,6 +42,7 @@ #include "mem/slicc/slicc_global.hh" #include "mem/slicc/ast/DeclAST.hh" #include "mem/slicc/ast/DeclListAST.hh" +#include "mem/slicc/ast/TypeFieldAST.hh" #include "mem/slicc/symbols/StateMachine.hh" class MachineAST : public DeclAST { @@ -49,6 +50,8 @@ public: // Constructors MachineAST(string* ident_ptr, PairListAST* pairs_ptr, + Vector<TypeFieldAST*>* config_params_ptr, + std::vector<std::string*>* latency_vector, DeclListAST* decl_list_ptr); // Destructor @@ -66,8 +69,10 @@ private: MachineAST& operator=(const MachineAST& obj); // Data Members (m_ prefix) + std::vector<std::string*>* m_latency_vector; string* m_ident_ptr; DeclListAST* m_decl_list_ptr; + Vector<TypeFieldAST*>* m_config_params_ptr; PairListAST* m_pairs_ptr; }; diff --git a/src/mem/slicc/ast/MethodCallExprAST.cc b/src/mem/slicc/ast/MethodCallExprAST.cc index 0e2fed769..1bfe312ff 100644 --- a/src/mem/slicc/ast/MethodCallExprAST.cc +++ b/src/mem/slicc/ast/MethodCallExprAST.cc @@ -76,25 +76,38 @@ Type* MethodCallExprAST::generate(string& code) const { Type* obj_type_ptr = NULL; + string methodId; + Vector <Type*> paramTypes; + + int actual_size = m_expr_vec_ptr->size(); + for(int i=0; i<actual_size; i++) { + string tmp; + Type* actual_type_ptr = (*m_expr_vec_ptr)[i]->generate(tmp); + paramTypes.insertAtBottom(actual_type_ptr); + } + if(m_obj_expr_ptr) { // member method call + string tmp; + obj_type_ptr = m_obj_expr_ptr->generate(tmp); + methodId = obj_type_ptr->methodId(*m_proc_name_ptr, paramTypes); + if (obj_type_ptr->methodReturnType(methodId)->isInterface()) + code += "static_cast<" + obj_type_ptr->methodReturnType(methodId)->cIdent() + "&>"; code += "(("; - obj_type_ptr = m_obj_expr_ptr->generate(code); - + code += tmp; code += ")."; } else if (m_type_ptr) { // class method call code += "(" + m_type_ptr->toString() + "::"; obj_type_ptr = m_type_ptr->lookupType(); + methodId = obj_type_ptr->methodId(*m_proc_name_ptr, paramTypes); } else { // impossible assert(0); } - Vector <Type*> paramTypes; - // generate code - int actual_size = m_expr_vec_ptr->size(); + actual_size = m_expr_vec_ptr->size(); code += (*m_proc_name_ptr) + "("; for(int i=0; i<actual_size; i++) { if (i != 0) { @@ -102,12 +115,9 @@ Type* MethodCallExprAST::generate(string& code) const } // Check the types of the parameter Type* actual_type_ptr = (*m_expr_vec_ptr)[i]->generate(code); - paramTypes.insertAtBottom(actual_type_ptr); } code += "))"; - string methodId = obj_type_ptr->methodId(*m_proc_name_ptr, paramTypes); - // Verify that this is a method of the object if (!obj_type_ptr->methodExist(methodId)) { error("Invalid method call: Type '" + obj_type_ptr->toString() + "' does not have a method '" + methodId + "'"); diff --git a/src/mem/slicc/ast/NewExprAST.cc b/src/mem/slicc/ast/NewExprAST.cc new file mode 100644 index 000000000..95e57192f --- /dev/null +++ b/src/mem/slicc/ast/NewExprAST.cc @@ -0,0 +1,9 @@ + +#include "mem/slicc/ast/NewExprAST.hh" + +Type* NewExprAST::generate(string & code) const +{ + Type* type = m_type_ptr->lookupType(); + code += "new " + type->cIdent(); + return type; +} diff --git a/src/mem/slicc/ast/NewExprAST.hh b/src/mem/slicc/ast/NewExprAST.hh new file mode 100644 index 000000000..375f130d6 --- /dev/null +++ b/src/mem/slicc/ast/NewExprAST.hh @@ -0,0 +1,20 @@ +#ifndef NEWEXPRAST_H +#define NEWEXPRAST_H + +#include "mem/slicc/ast/ExprAST.hh" +#include "mem/slicc/ast/TypeAST.hh" +#include "mem/slicc/symbols/Type.hh" + +class NewExprAST : public ExprAST +{ +public: + NewExprAST(TypeAST* type_ptr) : ExprAST() { m_type_ptr = type_ptr; } + Type* generate(string & code) const; + void print(ostream & out) const { out << "[NewExprAST: " << *m_type_ptr << "]"; } + string getName() const { return m_type_ptr->toString(); } + +private: + TypeAST* m_type_ptr; +}; + +#endif diff --git a/src/mem/slicc/ast/ObjDeclAST.cc b/src/mem/slicc/ast/ObjDeclAST.cc index f9349f9de..3569395db 100644 --- a/src/mem/slicc/ast/ObjDeclAST.cc +++ b/src/mem/slicc/ast/ObjDeclAST.cc @@ -108,32 +108,21 @@ void ObjDeclAST::generate() c_code = "m_version"; } else if (*m_ident_ptr == "machineID") { c_code = "m_machineID"; - } else if (*m_ident_ptr == "sequencer") { - c_code = "*(dynamic_cast<"+m_type_ptr->toString()+"*>(m_chip_ptr->getSequencer(m_version)))"; - machineComponentSym = true; - } /*else if (*m_ident_ptr == "xfdr_record_mgr") { - c_code = "*(dynamic_cast<"+m_type_ptr->toString()+"*>(m_chip_ptr->getXfdrManager(m_version)))"; - machineComponentSym = true; - } */else if (// getPairs().exist("network") || (m_type_ptr->lookupType()->existPair("cache")) -// || (m_type_ptr->lookupType()->existPair("tbe")) || -// (m_type_ptr->lookupType()->existPair("newtbe")) || -// (m_type_ptr->lookupType()->existPair("timer")) || -// (m_type_ptr->lookupType()->existPair("dir")) || -// (m_type_ptr->lookupType()->existPair("persistent")) || -// (m_type_ptr->lookupType()->existPair("filter")) || -// (getPairs().exist("trigger_queue")) - getPairs().exist("no_vector")) { - c_code = "(*(m_chip_ptr->m_" + machine + *m_ident_ptr + "_ptr))"; - machineComponentSym = true; } else { - c_code = "(*(m_chip_ptr->m_" + machine + *m_ident_ptr + "_vec[m_version]))"; - machineComponentSym = true; + c_code = "(*m_" + machine + *m_ident_ptr + "_ptr)"; + // c_code = "(*(m_chip_ptr->m_" + machine + *m_ident_ptr + "_ptr))"; + // machineComponentSym = true; } Var* v = new Var(*m_ident_ptr, getLocation(), type_ptr, c_code, getPairs(), g_sym_table.getStateMachine()); - g_sym_table.newSym(v); + StateMachine* machine_ptr = g_sym_table.getStateMachine(); + if (machine_ptr != NULL) { + machine_ptr->addObj(v); + }// else { + g_sym_table.newSym(v); + //} // used to cheat-- that is, access components in other machines if (machineComponentSym) { diff --git a/src/mem/slicc/parser/lexer.ll b/src/mem/slicc/parser/lexer.ll index a4af2ac51..b2d36855b 100644 --- a/src/mem/slicc/parser/lexer.ll +++ b/src/mem/slicc/parser/lexer.ll @@ -1,3 +1,4 @@ + /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -26,11 +27,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + * $Id$ + */ + %{ #include <assert.h> #include "mem/slicc/ast/ASTs.hh" -#include "mem/slicc/parser/parser.hh" +#include "parser.hh" #include <string> extern "C" int yylex(); @@ -76,6 +81,7 @@ return { return RETURN; } THIS { return THIS; } CHIP { return CHIP; } void { yylval.str_ptr = new string(yytext); return VOID; } +new { return NEW; } == { yylval.str_ptr = new string(yytext); return EQ; } != { yylval.str_ptr = new string(yytext); return NE; } @@ -108,6 +114,7 @@ void { yylval.str_ptr = new string(yytext); return VOID; } [0-9]*[.][0-9]* { yylval.str_ptr = new string(yytext); return FLOATNUMBER; } [0-9]* { yylval.str_ptr = new string(yytext); return NUMBER; } + [a-zA-Z_][a-zA-Z_0-9]{0,50} { yylval.str_ptr = new string(yytext); return IDENT; } \"[^"\n]*\" { yytext[strlen(yytext)-1] = '\0'; yylval.str_ptr = new string(yytext+1); return STRING; } \'[^'\n]*\' { yytext[strlen(yytext)-1] = '\0'; yylval.str_ptr = new string(yytext+1); return STRING; } diff --git a/src/mem/slicc/parser/parser.yy b/src/mem/slicc/parser/parser.yy index 724184665..81cbec9c2 100644 --- a/src/mem/slicc/parser/parser.yy +++ b/src/mem/slicc/parser/parser.yy @@ -1,3 +1,4 @@ + /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. @@ -26,11 +27,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + * $Id$ + * + * */ + %{ #include <string> #include <stdio.h> #include <assert.h> #include "mem/slicc/ast/ASTs.hh" +#include <vector> #define YYMAXDEPTH 100000 #define YYERROR_VERBOSE @@ -45,6 +52,7 @@ extern "C" int yylex(); %union { string* str_ptr; Vector<string>* string_vector_ptr; + std::vector<string*>* stdstring_vector_ptr; // Decls DeclAST* decl_ptr; @@ -103,6 +111,8 @@ extern "C" int yylex(); %type <expr_ptr> expr literal enumeration %type <expr_vector_ptr> expr_list +%type <stdstring_vector_ptr> myrule + %type <pair_ptr> pair %type <pair_list_ptr> pair_list pairs @@ -115,7 +125,7 @@ extern "C" int yylex(); //%token DEQUEUE REMOVE_EARLY SKIP_EARLY PEEK_EARLY %token DEBUG_EXPR_TOKEN DEBUG_MSG_TOKEN %token ACTION_DECL TRANSITION_DECL TYPE_DECL STRUCT_DECL EXTERN_TYPE_DECL ENUM_DECL -%token TYPE_FIELD OTHER IF ELSE RETURN +%token TYPE_FIELD OTHER IF ELSE RETURN NEW %token <str_ptr> EQ NE '<' '>' LE GE NOT AND OR PLUS DASH STAR SLASH RIGHTSHIFT LEFTSHIFT @@ -138,7 +148,9 @@ decls: decl decls { $2->insertAtTop($1); $$ = $2; } | { $$ = new Vector<DeclAST*>; } ; -decl: MACHINE_DECL '(' ident pair_list ')' '{' decl_list '}' { $$ = new MachineAST($3, $4, $7); } +decl: MACHINE_DECL '(' ident pair_list ')' ':' myrule '{' decl_list '}' { $$ = new MachineAST($3, $4, NULL, $7, $9); } +// | MACHINE_DECL '(' ident pair_list ')' ':' type_members '{' decl_list '}' { $$ = new MachineAST($3, $4, $7, string_vector, $9); } + | MACHINE_DECL '(' ident pair_list ')' '{' decl_list '}' { $$ = new MachineAST($3, $4, NULL, new vector<string*>(), $7); } | ACTION_DECL '(' ident pair_list ')' statement_list { $$ = new ActionDeclAST($3, $4, $6); } | IN_PORT_DECL '(' ident ',' type ',' var pair_list ')' statement_list { $$ = new InPortDeclAST($3, $5, $7, $8, $10); } | OUT_PORT_DECL '(' ident ',' type ',' var pair_list ')' SEMICOLON { $$ = new OutPortDeclAST($3, $5, $7, $8); } @@ -214,7 +226,7 @@ formal_param : type ident { $$ = new FormalParamAST($1, $2); } ; // Idents and lists -ident: IDENT { $$ = $1; } ; +ident: IDENT { $$ = $1; }; ident_list: '{' idents '}' { $$ = $2; } | ident { $$ = new Vector<string>; $$->insertAtTop(*($1)); delete $1; } @@ -274,7 +286,7 @@ expr: var { $$ = $1; } | literal { $$ = $1; } | enumeration { $$ = $1; } | ident '(' expr_list ')' { $$ = new FuncCallExprAST($1, $3); } - + | NEW type { $$ = new NewExprAST($2); } // globally access a local chip component and call a method | THIS DOT var '[' expr ']' DOT var DOT ident '(' expr_list ')' { $$ = new ChipComponentAccessAST($3, $5, $8, $10, $12 ); } @@ -324,6 +336,10 @@ var: ident { $$ = new VarExprAST($1); } field: ident { $$ = $1; } ; +myrule: myrule IDENT { $1->push_back($2); } + | IDENT { $$ = new vector<string*>(1, $1); } + ; + %% extern FILE *yyin; @@ -337,7 +353,7 @@ DeclListAST* parse(string filename) exit(1); } g_line_number = 1; - g_file_name() = filename; + g_file_name = filename; yyin = file; g_decl_list_ptr = NULL; yyparse(); @@ -346,7 +362,7 @@ DeclListAST* parse(string filename) extern "C" void yyerror(char* s) { - fprintf(stderr, "%s:%d: %s at %s\n", g_file_name().c_str(), g_line_number, s, yytext); + fprintf(stderr, "%s:%d: %s at %s\n", g_file_name.c_str(), g_line_number, s, yytext); exit(1); } diff --git a/src/mem/slicc/symbols/Func.cc b/src/mem/slicc/symbols/Func.cc index 6bc763300..d29138b38 100644 --- a/src/mem/slicc/symbols/Func.cc +++ b/src/mem/slicc/symbols/Func.cc @@ -88,7 +88,7 @@ void Func::funcPrototype(string& code) const } // This write a function of object Chip -void Func::writeCFiles(string path) const +void Func::writeCFiles(string path) { if (isExternal()) { // Do nothing @@ -99,9 +99,8 @@ void Func::writeCFiles(string path) const out << "/** Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< " */" << endl; out << endl; out << "#include \"mem/protocol/Types.hh\"" << endl; - out << "#include \"mem/protocol/Chip.hh\"" << endl; if (m_isInternalMachineFunc) { - out << "#include \"" << m_machineStr << "_Controller.hh\"" << endl; + out << "#include \"mem/protocol/" << m_machineStr << "_Controller.hh\"" << endl; } out << endl; diff --git a/src/mem/slicc/symbols/Func.hh b/src/mem/slicc/symbols/Func.hh index 6ceaba378..8f8548bb0 100644 --- a/src/mem/slicc/symbols/Func.hh +++ b/src/mem/slicc/symbols/Func.hh @@ -57,7 +57,7 @@ public: 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) const; + void writeCFiles(string path) ; void funcPrototype(string& code) const; bool isExternal() const { return existPair("external"); } bool isInternalMachineFunc() const { return m_isInternalMachineFunc; } diff --git a/src/mem/slicc/symbols/StateMachine.cc b/src/mem/slicc/symbols/StateMachine.cc index 6aaa0ebca..f2a40d3d7 100644 --- a/src/mem/slicc/symbols/StateMachine.cc +++ b/src/mem/slicc/symbols/StateMachine.cc @@ -44,10 +44,13 @@ #include "mem/gems_common/util.hh" #include "mem/gems_common/Vector.hh" -StateMachine::StateMachine(string ident, const Location& location, const Map<string, string>& pairs) +#include <set> + +StateMachine::StateMachine(string ident, const Location& location, const Map<string, string>& pairs, std::vector<std::string*>* latency_vector) : Symbol(ident, location, pairs) { m_table_built = false; + m_latency_vector = *latency_vector; } StateMachine::~StateMachine() @@ -167,11 +170,18 @@ const Transition* StateMachine::getTransPtr(int stateIndex, int eventIndex) cons // ******* C Files ******* // // *********************** // -void StateMachine::writeCFiles(string path) const +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; @@ -186,13 +196,6 @@ void StateMachine::writeCFiles(string path) const conditionally_write_file(path + comp + "_Controller.cc", sstr); } - // Output the method declarations for the class declaration - { - ostringstream sstr; - printControllerH(sstr, comp); - conditionally_write_file(path + comp + "_Controller.hh", sstr); - } - // Output the wakeup loop for the events { ostringstream sstr; @@ -219,8 +222,11 @@ void StateMachine::writeCFiles(string path) const } -void StateMachine::printControllerH(ostream& out, string component) const +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; @@ -232,29 +238,59 @@ void StateMachine::printControllerH(ostream& out, string component) const 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 Consumer {" << 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 << " friend class Chip;" << endl; out << "#endif /* CHECK_COHERENCE */" << endl; out << "public:" << endl; - out << " " << component << "_Controller(Chip* chip_ptr, int version);" << 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 << " static void dumpStats(ostream& out) { s_profiler.dumpStats(out); }" << endl; - out << " static void clearStats() { s_profiler.clearStats(); }" << 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; + std::vector<std::string*>::const_iterator it; + for(it=m_latency_vector.begin();it!=m_latency_vector.end();it++){ + out << " int m_" << (*it)->c_str() << ";" << 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) { @@ -267,11 +303,16 @@ void StateMachine::printControllerH(ostream& out, string component) const out << ", int priority"; } out << "); // in " << component << "_Transitions.cc" << endl; - out << " Chip* m_chip_ptr;" << endl; - out << " NodeID m_id;" << 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 << " static " << component << "_Profiler s_profiler;" << endl; + out << " static int m_num_controllers;" << endl; // internal function protypes out << " // Internal functions" << endl; @@ -290,11 +331,30 @@ void StateMachine::printControllerH(ostream& out, string component) const 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) const +void StateMachine::printControllerC(ostream& out, string component) { out << "/** \\file " << getIdent() << ".cc" << endl; out << " * " << endl; @@ -309,9 +369,22 @@ void StateMachine::printControllerC(ostream& out, string component) const out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl; out << "#include \"mem/protocol/Types.hh\"" << endl; out << "#include \"mem/ruby/system/System.hh\"" << endl; - out << "#include \"mem/protocol/Chip.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; @@ -322,26 +395,220 @@ void StateMachine::printControllerC(ostream& out, string component) const out << "/** \\brief constructor */" << endl; out << component << "_Controller::" << component - << "_Controller(Chip* chip_ptr, int version)" << endl; + // << "_Controller(int version, Network* net_ptr)" << endl; + << "_Controller(const string & name)" << endl; + out << " : m_name(name)" << endl; + out << "{ " << 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 << " m_chip_ptr = chip_ptr;" << endl; - out << " m_id = m_chip_ptr->getID();" << endl; - out << " m_version = version;" << 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_latency_vector.size()) { + out << " else { " << endl; + std::vector<std::string*>::const_iterator it; + for(it=m_latency_vector.begin();it!=m_latency_vector.end();it++) { + string str = (*it)->c_str(); + str.erase(0,8); +//convert to lowercase + size_t i; + char* strc = (char*) malloc (str.length()+1); + strc[str.length()]=0; + for(i=0; i < str.length(); i++) { + strc[i] = str.at(i); + strc[i] = tolower(strc[i]); + } + str = strc; + delete strc; + out << " if (argv[i] == \"" << str << "\"){" << endl; + if (str == "to_mem_ctrl_latency") + out << " m_" << (*it)->c_str() << "=" << "atoi(argv[i+1].c_str())+(random() % 5);" << endl; + else + out << " m_" << (*it)->c_str() << "=" << "atoi(argv[i+1].c_str());" << endl; +// out << " printf (\"SET m_" << it->c_str() << "= %i \\n \", m_" << it->c_str() << ");" << endl; + out << " }" << endl; + } + out << " }" << endl; + } + out << " }" << endl; + + out << " m_net_ptr = net_ptr;" << endl; out << " m_machineID.type = MachineType_" << component << ";" << endl; - out << " m_machineID.num = m_id*RubyConfig::numberOf"<< component << "PerChip()+m_version;" << endl; + out << " m_machineID.num = m_version;" << endl; + +// out << " printf (\"I set m_LATENCY_ISSUE_LATENCY to %i \\n \", m_LATENCY_ISSUE_LATENCY);" << endl; +// out << " printf (\"I set m_LATENCY_CACHE_RESPONSE_LATENCY to %i \\n \", m_LATENCY_CACHE_RESPONSE_LATENCY);" << 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; + 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; } - out << 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(\"[Chip \" + int_to_string(m_chip_ptr->getID()) + \" \" + int_to_string(m_version) + \", " + << ".setDescription(\"[Version \" + int_to_string(m_version) + \", " << component << ", " << port->toString() << "]\");" << endl; } @@ -368,12 +635,72 @@ void StateMachine::printControllerC(ostream& out, string component) const } } + //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_chip_ptr->getID() << \" \" << m_version << \"]\"; }" << endl; + << "_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; @@ -387,14 +714,39 @@ void StateMachine::printControllerC(ostream& out, string component) const << action.getIdent() << "(const Address& addr)" << endl; out << "{" << endl; out << " DEBUG_MSG(GENERATED_COMP, HighPrio,\"executing\");" << endl; - out << action.lookupPair("c_code"); +//added by SS +//instead of rubyconfig:: --> it should point to m_latency... +//so I should change the string output of this lookup + + string c_code_string = action.lookupPair("c_code"); + + size_t found = c_code_string.find("RubyConfig::get"); + + if (found!=string::npos){ //found --> replace it with local access + //if it is related to latency --> replace it + std::vector<std::string*>::const_iterator it; + for(it=m_latency_vector.begin();it!=m_latency_vector.end();it++){ + string str = (*it)->c_str(); + str.erase(0,8); + size_t fd = c_code_string.find(str, found); + if (fd!=string::npos && (fd == found+15)){ + string rstr = "m_"; + rstr += (*it)->c_str(); + c_code_string.replace(found,15+str.size()+2,rstr); + break; + } + } + } + + out << c_code_string; + out << "}" << endl; } out << endl; } } -void StateMachine::printCWakeup(ostream& out, string component) const +void StateMachine::printCWakeup(ostream& out, string component) { out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; out << "// " << getIdent() << ": " << getShorthand() << endl; @@ -406,7 +758,6 @@ void StateMachine::printCWakeup(ostream& out, string component) const out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl; out << "#include \"mem/protocol/Types.hh\"" << endl; out << "#include \"mem/ruby/system/System.hh\"" << endl; - out << "#include \"mem/protocol/Chip.hh\"" << endl; out << endl; out << "void " << component << "_Controller::wakeup()" << endl; out << "{" << endl; @@ -416,8 +767,8 @@ void StateMachine::printCWakeup(ostream& out, string component) const 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 <= RubyConfig::" << getIdent() << "TransitionsPerCycle());" << endl; - out << " if (counter == RubyConfig::" << getIdent() << "TransitionsPerCycle()) {" << 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; @@ -442,7 +793,7 @@ void StateMachine::printCWakeup(ostream& out, string component) const out << endl; } -void StateMachine::printCSwitch(ostream& out, string component) const +void StateMachine::printCSwitch(ostream& out, string component) { out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; out << "// " << getIdent() << ": " << getShorthand() << endl; @@ -453,7 +804,6 @@ void StateMachine::printCSwitch(ostream& out, string component) const out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl; out << "#include \"mem/protocol/Types.hh\"" << endl; out << "#include \"mem/ruby/system/System.hh\"" << endl; - out << "#include \"mem/protocol/Chip.hh\"" << endl; out << endl; out << "#define HASH_FUN(state, event) ((int(state)*" << component << "_Event_NUM)+int(event))" << endl; @@ -490,9 +840,9 @@ void StateMachine::printCSwitch(ostream& out, string component) const 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 (PROTOCOL_DEBUG_TRACE) {" << endl + out << " if (Debug::getProtocolTrace()) {" << endl << " g_system_ptr->getProfiler()->profileTransition(\"" << component - << "\", m_chip_ptr->getID(), m_version, addr, " << endl + << "\", 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 @@ -501,9 +851,9 @@ void StateMachine::printCSwitch(ostream& out, string component) const out << " " << component << "_setState(addr, next_state);" << endl; out << " " << endl; out << " } else if (result == TransitionResult_ResourceStall) {" << endl; - out << " if (PROTOCOL_DEBUG_TRACE) {" << endl + out << " if (Debug::getProtocolTrace()) {" << endl << " g_system_ptr->getProfiler()->profileTransition(\"" << component - << "\", m_chip_ptr->getID(), m_version, addr, " << endl + << "\", m_version, addr, " << endl << " " << component << "_State_to_string(state), " << endl << " " << component << "_Event_to_string(event), " << endl << " " << component << "_State_to_string(next_state), " << endl @@ -512,9 +862,9 @@ void StateMachine::printCSwitch(ostream& out, string component) const out << " } else if (result == TransitionResult_ProtocolStall) {" << endl; out << " DEBUG_MSG(GENERATED_COMP,HighPrio,\"stalling\");" << endl << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl; - out << " if (PROTOCOL_DEBUG_TRACE) {" << endl + out << " if (Debug::getProtocolTrace()) {" << endl << " g_system_ptr->getProfiler()->profileTransition(\"" << component - << "\", m_chip_ptr->getID(), m_version, addr, " << endl + << "\", m_version, addr, " << endl << " " << component << "_State_to_string(state), " << endl << " " << component << "_Event_to_string(event), " << endl << " " << component << "_State_to_string(next_state), " << endl @@ -630,7 +980,6 @@ void StateMachine::printCSwitch(ostream& out, string component) const } out << " default:" << endl; - out << " WARN_EXPR(m_id);" << endl; out << " WARN_EXPR(m_version);" << endl; out << " WARN_EXPR(g_eventQueue_ptr->getTime());" << endl; out << " WARN_EXPR(addr);" << endl; @@ -642,7 +991,7 @@ void StateMachine::printCSwitch(ostream& out, string component) const out << "}" << endl; } -void StateMachine::printProfilerH(ostream& out, string component) const +void StateMachine::printProfilerH(ostream& out, string component) { out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; out << "// " << getIdent() << ": " << getShorthand() << endl; @@ -669,7 +1018,7 @@ void StateMachine::printProfilerH(ostream& out, string component) const out << "#endif // " << component << "_PROFILER_H" << endl; } -void StateMachine::printProfilerC(ostream& out, string component) const +void StateMachine::printProfilerC(ostream& out, string component) { out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; out << "// " << getIdent() << ": " << getShorthand() << endl; @@ -769,7 +1118,7 @@ string frameRef(string href, string target, string target_num, string text) } -void StateMachine::writeHTMLFiles(string path) const +void StateMachine::writeHTMLFiles(string path) { string filename; string component = getIdent(); @@ -841,7 +1190,7 @@ void StateMachine::writeHTMLFiles(string path) const } } -void StateMachine::printHTMLTransitions(ostream& out, int active_state) const +void StateMachine::printHTMLTransitions(ostream& out, int active_state) { // -- Prolog out << "<HTML><BODY link=\"blue\" vlink=\"blue\">" << endl; diff --git a/src/mem/slicc/symbols/StateMachine.hh b/src/mem/slicc/symbols/StateMachine.hh index 02ab12881..101e38547 100644 --- a/src/mem/slicc/symbols/StateMachine.hh +++ b/src/mem/slicc/symbols/StateMachine.hh @@ -39,6 +39,9 @@ #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; @@ -50,7 +53,7 @@ class Func; class StateMachine : public Symbol { public: // Constructors - StateMachine(string ident, const Location& location, const Map<string, string>& pairs); + StateMachine(string ident, const Location& location, const Map<string, string>& pairs, std::vector<std::string*>* latency_vector); // Destructor ~StateMachine(); @@ -65,6 +68,7 @@ public: 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]; } @@ -72,21 +76,26 @@ public: 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) const; - void writeHTMLFiles(string path) const; + void writeCFiles(string path) ; + void writeHTMLFiles(string path) ; void print(ostream& out) const { out << "[StateMachine: " << toString() << "]" << endl; } private: + + std::vector<std::string*> m_latency_vector; + // Private Methods void checkForDuplicate(const Symbol& sym) const; @@ -97,14 +106,14 @@ private: // StateMachine(const StateMachine& obj); // StateMachine& operator=(const StateMachine& obj); - void printControllerH(ostream& out, string component) const; - void printControllerC(ostream& out, string component) const; - void printCWakeup(ostream& out, string component) const; - void printCSwitch(ostream& out, string component) const; - void printProfilerH(ostream& out, string component) const; - void printProfilerC(ostream& out, string component) const; + 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) const; + void printHTMLTransitions(ostream& out, int active_state) ; // Data Members (m_ prefix) Vector<State*> m_states; @@ -118,10 +127,15 @@ private: 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 diff --git a/src/mem/slicc/symbols/Symbol.hh b/src/mem/slicc/symbols/Symbol.hh index 1b4bd517a..4a1c5e44e 100644 --- a/src/mem/slicc/symbols/Symbol.hh +++ b/src/mem/slicc/symbols/Symbol.hh @@ -65,8 +65,8 @@ public: void addPair(const string& key, const string& value); // virtual string getCode() const = 0; - virtual void writeCFiles(string path) const {} - virtual void writeHTMLFiles(string path) const {} + virtual void writeCFiles(string path) {} + virtual void writeHTMLFiles(string path) {} virtual void print(ostream& out) const { out << "[Symbol: " << getIdent() << "]"; } private: diff --git a/src/mem/slicc/symbols/SymbolTable.cc b/src/mem/slicc/symbols/SymbolTable.cc index e598ffcb4..8af3685f8 100644 --- a/src/mem/slicc/symbols/SymbolTable.cc +++ b/src/mem/slicc/symbols/SymbolTable.cc @@ -27,6 +27,15 @@ * 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" @@ -163,7 +172,7 @@ void SymbolTable::writeCFiles(string path) const { int size = m_sym_vec.size(); { - // Write the mem/protocol/Types.hh include file for the types + // Write the Types.hh include file for the types ostringstream sstr; sstr << "/** Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< " */" << endl; sstr << endl; @@ -182,685 +191,69 @@ void SymbolTable::writeCFiles(string path) const m_sym_vec[i]->writeCFiles(path + '/'); } - writeChipFiles(path); + writeControllerFactory(path); } -void SymbolTable::writeChipFiles(string path) const +void SymbolTable::writeControllerFactory(string path) const { - // Create Chip.cc and mem/protocol/Chip.hh - - // FIXME - Note: this method is _really_ ugly. Most of this - // functionality should be pushed into each type of symbol and use - // virtual methods to get the right behavior for each type of - // symbol. This is also more flexible, and much cleaner. - + ostringstream sstr; int size = m_sym_vec.size(); - // Create Chip.h - { - ostringstream sstr; - sstr << "/** \\file Chip.h " << endl; - sstr << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<<endl; - sstr << " */ " <<endl<<endl; - - sstr << "#ifndef CHIP_H" << endl; - sstr << "#define CHIP_H" << endl; - sstr << endl; + sstr << "/** \\file ControllerFactory.hh " << endl; + sstr << " * Auto generatred C++ code started by " << __FILE__ << ":" << __LINE__ << endl; + sstr << " */" << endl << endl; - // Includes - sstr << "#include \"mem/ruby/common/Global.hh\"" << endl; - sstr << "#include \"mem/protocol/Types.hh\"" << endl; - sstr << "#include \"mem/ruby/slicc_interface/AbstractChip.hh\"" << endl; - sstr << "class Network;" << endl; - sstr << endl; - - // Class declarations for all Machines/Controllers - for(int i=0; i<size; i++) { - StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]); - if (machine != NULL) { - sstr << "class " << machine->getIdent() << "_Controller;" << endl; - } - } + sstr << "#ifndef CONTROLLERFACTORY_H" << endl; + sstr << "#define CONTROLLERFACTORY_H" << endl; + sstr << endl; - sstr << "class Chip : public AbstractChip {" << endl; - sstr << "public:" << endl; - sstr << endl; - sstr << " // Constructors" << endl; - sstr << " Chip(NodeID chip_number, Network* net_ptr);" << endl; - sstr << endl; - sstr << " // Destructor" << endl; - sstr << " ~Chip();" << endl; - sstr << endl; - sstr << " // Public Methods" << endl; - sstr << " void recordCacheContents(CacheRecorder& tr) const;" << endl; - sstr << " void dumpCaches(ostream& out) const;" << endl; - sstr << " void dumpCacheData(ostream& out) const;" << endl; - sstr << " static void printStats(ostream& out);" << endl; - sstr << " static void clearStats();" << endl; - sstr << " void printConfig(ostream& out);" << endl; - sstr << " void print(ostream& out) const;" << endl; - - // Used by coherence checker - sstr << "#ifdef CHECK_COHERENCE" << endl; - sstr << " bool isBlockShared(const Address& addr) const;" << endl; - sstr << " bool isBlockExclusive(const Address& addr) const;" << endl; - sstr << "#endif /* CHECK_COHERENCE */" << endl; + Vector< string > controller_types; - sstr << endl; - sstr << "private:" << endl; - sstr << " // Private copy constructor and assignment operator" << endl; - sstr << " Chip(const Chip& obj);" << endl; - sstr << " Chip& operator=(const Chip& obj);" << endl; - sstr << endl; - sstr << "public: // FIXME - these should not be public" << endl; - sstr << " // Data Members (m_ prefix)" << endl; - sstr << endl; - sstr << " Chip* m_chip_ptr;" << endl; - sstr << endl; - sstr << " // SLICC object variables" << endl; - sstr << endl; + // includes + sstr << "#include <string>" << endl; + sstr << "class Network;" << endl; + sstr << "class AbstractController;" << endl; + sstr << endl; - // Look at all 'Vars' - for(int i=0; i<size; i++) { - Var* var = dynamic_cast<Var*>(m_sym_vec[i]); - if (var != NULL) { - if (var->existPair("chip_object")) { - if (var->existPair("no_chip_object")) { - // Do nothing - } else { - string template_hack = ""; - if (var->existPair("template_hack")) { - template_hack = var->lookupPair("template_hack"); - } - if (// var->existPair("network") || var->getType()->existPair("cache") || -// var->getType()->existPair("tbe") || var->getType()->existPair("newtbe") || -// var->getType()->existPair("dir") || var->getType()->existPair("persistent") || -// var->getType()->existPair("filter") || var->getType()->existPair("timer") || -// var->existPair("trigger_queue") - var->existPair("no_vector") - ) { - sstr << " " << var->getType()->cIdent() << template_hack << "* m_" - << var->cIdent() << "_ptr;" << endl; - } else { - // create pointer except those created in AbstractChip - if (!(var->existPair("abstract_chip_ptr"))) { - sstr << " Vector < " << var->getType()->cIdent() << template_hack - << "* > m_" << var->cIdent() << "_vec;" << 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 << endl; - sstr << " // SLICC machine/controller variables" << endl; + sstr << "#endif // CONTROLLERFACTORY_H" << endl; + conditionally_write_file(path + "/ControllerFactory.hh", sstr); - // Look at all 'Machines' - for(int i=0; i<size; i++) { - StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]); - if (machine != NULL) { - string ident = machine->getIdent() + "_Controller"; - sstr << " Vector < " << ident << "* > m_" << ident << "_vec;\n"; - } - } + // ControllerFactory.cc file - sstr << endl; + sstr.str(""); - sstr << " // machine external SLICC function decls\n"; + sstr << "/** \\file ControllerFactory.cc " << endl; + sstr << " * Auto generatred C++ code started by " << __FILE__ << ":" << __LINE__ << endl; + sstr << " */" << endl << endl; - // Look at all 'Functions' - for(int i=0; i<size; i++) { - Func* func = dynamic_cast<Func*>(m_sym_vec[i]); - if (func != NULL) { - string proto; - func->funcPrototype(proto); - if (proto != "") { - sstr << " " << proto; - } - } + // 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 << endl; - sstr << "#endif // CHIP_H" << endl; - - conditionally_write_file(path + "/Chip.hh", sstr); } - // Create Chip.cc - { - ostringstream sstr; - sstr << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<<endl<<endl; - sstr << "#include \"mem/protocol/Chip.hh\"" << endl; - sstr << "#include \"mem/ruby/network/Network.hh\"" << endl; - sstr << "#include \"mem/ruby/recorder/CacheRecorder.hh\"" << endl; - sstr << "" << endl; - - sstr << "// Includes for controllers" << 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; - } - } - - sstr << "" << endl; - sstr << "Chip::Chip(NodeID id, Network* net_ptr):AbstractChip(id, net_ptr)" << endl; - sstr << "{" << endl; - sstr << " m_chip_ptr = this;" << endl; - - // FIXME - WHY IS THIS LOOP HERE? - // WE SEEM TO BE CREATING A SEQUENCER HERE THEN OVERWRITTING THAT INSTANITATION - // IN THE NEXT LOOP -// // find sequencer's type -// for(int i=0; i<size; i++) { -// Var* var = dynamic_cast<Var*>(m_sym_vec[i]); -// if(var && var->cIdent() == "sequencer") -// sstr << " m_sequencer_ptr = new " << var->getType()->cIdent() << "(this);\n"; -// } - - // Look at all 'Vars' - for(int i=0; i<size; i++) { - Var* var = dynamic_cast<Var*>(m_sym_vec[i]); - if (var != NULL && var->existPair("chip_object") && !var->existPair("no_chip_object")) { - - sstr << " // " << var->cIdent() << endl; - if (!var->existPair("network")) { - // Not a network port object - if (var->getType()->existPair("primitive")) { - // Normal non-object - // sstr << " m_" << var->cIdent() << "_ptr = new " << var->getType()->cIdent() << ";\n"; - - sstr << " m_" << var->cIdent(); - sstr << "_vec.setSize(RubyConfig::numberOf"; - sstr << var->getMachine()->getIdent() << "PerChip(m_id));" << endl; - sstr << " for (int i = 0; i < RubyConfig::numberOf" << var->getMachine()->getIdent() - << "PerChip(m_id); i++) {" << endl; - sstr << " m_" << var->cIdent() << "_vec[i] = new " << var->getType()->cIdent() << ";\n"; - if (var->existPair("default")) { - sstr << " *(m_" << var->cIdent() << "_vec[i]) = " << var->lookupPair("default") << ";\n"; - } - sstr << " }\n"; - - } else { - - // Normal Object - string template_hack = ""; - if (var->existPair("template_hack")) { - template_hack = var->lookupPair("template_hack"); - } - if (// var->getType()->existPair("cache") || var->getType()->existPair("tbe") || -// var->getType()->existPair("newtbe") || var->getType()->existPair("timer") || -// var->getType()->existPair("dir") || var->getType()->existPair("persistent") || -// var->getType()->existPair("filter") || var->existPair("trigger_queue") - var->existPair("no_vector")) { - sstr << " m_" << var->cIdent() << "_ptr = new " << var->getType()->cIdent() << template_hack; - if (!var->getType()->existPair("non_obj") && (!var->getType()->isEnumeration())) { - if (var->existPair("constructor_hack")) { - string constructor_hack = var->lookupPair("constructor_hack"); - sstr << "(this, " << constructor_hack << ")"; - } else { - sstr << "(this)"; - } - } - sstr << ";\n"; - sstr << " assert(m_" << var->cIdent() << "_ptr != NULL);" << endl; - - if (var->existPair("default")) { - sstr << " (*m_" << var->cIdent() << "_ptr) = " << var->lookupPair("default") - << "; // Object default" << endl; - } else if (var->getType()->hasDefault()) { - sstr << " (*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"); - sstr << " m_" << var->cIdent() << "_ptr->setOrdering(" << ordered << ");\n"; - } - - // Set randomization - if (var->existPair("random")) { - // A buffer - string value = var->lookupPair("random"); - sstr << " 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"); - sstr << " m_" << var->cIdent() << "_ptr->setPriority(" << rank << ");\n"; - } - } else if ((var->getType()->existPair("mover")) && (var->getMachine()->getIdent() == "L2Cache")) { - // FIXME - dnuca mover is a special case - sstr << " m_" << var->cIdent() << "_ptr = NULL;" << endl; - sstr << " if (RubyConfig::isL2CacheDNUCAMoverChip(m_id)) {" << endl; - sstr << " m_" << var->cIdent() << "_ptr = new " << var->getType()->cIdent() << template_hack; - if (!var->getType()->existPair("non_obj") && (!var->getType()->isEnumeration())) { - if (var->existPair("constructor_hack")) { - string constructor_hack = var->lookupPair("constructor_hack"); - sstr << "(this, " << constructor_hack << ")"; - } else { - sstr << "(this)"; - } - } - sstr << ";\n"; - sstr << " }\n"; - } else if (var->getType()->existPair("mover") && ((var->getMachine()->getIdent() == "L1Cache") || (var->getMachine()->getIdent() == "Collector"))) { - sstr << " m_" << var->cIdent() << "_ptr = NULL;" << endl; - sstr << " \n"; - } else { - sstr << " m_" << var->cIdent(); - sstr << "_vec.setSize(RubyConfig::numberOf"; - sstr << var->getMachine()->getIdent() << "PerChip(m_id));" << endl; - sstr << " for (int i = 0; i < RubyConfig::numberOf" << var->getMachine()->getIdent() - << "PerChip(m_id); i++) {" << endl; - - - ostringstream tail; - tail << template_hack; - if (!var->getType()->existPair("non_obj") && (!var->getType()->isEnumeration())) { - if (var->existPair("constructor_hack")) { - string constructor_hack = var->lookupPair("constructor_hack"); - tail << "(this, " << constructor_hack << ")"; - } else { - tail << "(this)"; - } - } - tail << ";\n"; - - - if(var->existPair("child_selector")){ - string child_selector = var->lookupPair("child_selector"); - string child_types = var->lookupPair("child_types"); - string::iterator it = child_types.begin(); - - unsigned num_types = 0; - for(unsigned t=0;t<child_types.size();t++){ - if(child_types.at(t) == '<'){ - num_types++; - } - } - - string* types = new string[num_types]; - string* ids = new string[num_types]; - int type_idx = 0; - bool id_done = false; - for(unsigned t=0;t<child_types.size();t++){ - if(child_types[t] == '<'){ - id_done = false; - unsigned r; - for(r=t+1;child_types.at(r)!='>';r++){ - if(r == child_types.size()){ - cerr << "Parse error in child_types" << endl; - exit(EXIT_FAILURE); - } - if(child_types.at(r) == ' ') continue; //ignore whitespace - if(child_types.at(r) == ',') {id_done = true;continue;} - if(id_done == true) - types[type_idx].push_back(child_types.at(r)); - else - ids[type_idx].push_back(child_types.at(r)); - } - type_idx++; - t = r; - } - } - - for(unsigned t=0;t<num_types;t++){ - if(t==0) - sstr << " if(strcmp(" << child_selector << ", \"" << ids[t] << "\") == 0)" << endl; - else - sstr << " else if(strcmp(" << child_selector << ", \"" << ids[t] << "\") == 0)" << endl; - sstr << " m_" << var->cIdent() << "_vec[i] = new " << types[t] << tail.str() << endl; - } - } - else { - sstr << " m_" << var->cIdent() << "_vec[i] = new " << var->getType()->cIdent() << tail.str() << endl; - } - - sstr << " assert(m_" << var->cIdent() << "_vec[i] != NULL);" << endl; - if (var->existPair("ordered")) { - string ordered = var->lookupPair("ordered"); - sstr << " m_" << var->cIdent() << "_vec[i]->setOrdering(" << ordered << ");\n"; - } - if (var->existPair("rank")) { - string rank = var->lookupPair("rank"); - sstr << " m_" << var->cIdent() << "_vec[i]->setPriority(" << rank << ");\n"; - } - - // Set buffer size - if (var->getType()->isBuffer() && !var->existPair("infinite")) { - sstr << " if (FINITE_BUFFERING) {\n"; - sstr << " m_" << var->cIdent() << "_vec[i]->setSize(PROCESSOR_BUFFER_SIZE);\n"; - sstr << " }\n"; - } - - sstr << " }\n"; - } - } - - sstr << endl; - - } else { - // Network port object - string network = var->lookupPair("network"); - string ordered = var->lookupPair("ordered"); - string vnet = var->lookupPair("virtual_network"); - - if (var->getMachine() != NULL) { - sstr << " m_" << var->cIdent() << "_vec.setSize(RubyConfig::numberOf" - << var->getMachine()->getIdent() << "PerChip(m_id));" << endl; - sstr << " for (int i = 0; i < RubyConfig::numberOf" << var->getMachine()->getIdent() - << "PerChip(m_id); i++) {" << endl; - sstr << " m_" << var->cIdent() << "_vec[i] = m_net_ptr->get" - << network << "NetQueue(i+m_id*RubyConfig::numberOf" <<var->getMachine()->getIdent() - << "PerChip()+MachineType_base_number(string_to_MachineType(\"" - << var->getMachine()->getIdent() << "\")), " - << ordered << ", " << vnet << ");\n"; - sstr << " assert(m_" << var->cIdent() << "_vec[i] != NULL);" << endl; - } else { // old protocol - sstr << " m_" << var->cIdent() << "_vec.setSize(1);" << endl; - sstr << " for (int i = 0; i < 1; i++) {" << endl; - sstr << " m_" << var->cIdent() << "_vec[i] = m_net_ptr->get" - << network << "NetQueue(m_id, " - << ordered << ", " << vnet << ");\n"; - sstr << " assert(m_" << var->cIdent() << "_vec[i] != NULL);" << endl; - } - - // Set ordering - if (var->existPair("ordered")) { - // A buffer - string ordered = var->lookupPair("ordered"); - sstr << " m_" << var->cIdent() << "_vec[i]->setOrdering(" << ordered << ");\n"; - } - - // Set randomization - if (var->existPair("random")) { - // A buffer - string value = var->lookupPair("random"); - sstr << " m_" << var->cIdent() << "_vec[i]->setRandomization(" << value << ");\n"; - } - - // Set Priority - if (var->existPair("rank")) { - string rank = var->lookupPair("rank"); - sstr << " m_" << var->cIdent() << "_vec[i]->setPriority(" << rank << ");\n"; - } - - // Set buffer size - if (var->getType()->isBuffer()) { - sstr << " if (FINITE_BUFFERING) {\n"; - sstr << " m_" << var->cIdent() << "_vec[i]->setSize(PROTOCOL_BUFFER_SIZE);\n"; - sstr << " }\n"; - } - - sstr << " }\n"; - } - } - } - // Look at all 'Machines' - for(int i=0; i<size; i++) { - StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]); - if (machine != NULL) { - string ident = machine->getIdent() + "_Controller"; - sstr << " m_" << ident << "_vec.setSize(RubyConfig::numberOf" << machine->getIdent() - << "PerChip(m_id));" << endl; - sstr << " for (int i = 0; i < RubyConfig::numberOf" << machine->getIdent() - << "PerChip(m_id); i++) {" << endl; - sstr << " m_" << ident << "_vec[i] = new " << ident << "(this, i);\n"; - sstr << " assert(m_" << ident << "_vec[i] != NULL);" << endl; - sstr << " }\n"; - sstr << endl; - } - } - - sstr << "}" << endl; - sstr << endl; - sstr << "Chip::~Chip()\n"; - sstr << "{\n"; - -// // FIXME: sequencer shouldn' be manually handled -// sstr << " delete m_sequencer_ptr;" << endl; - - // Look at all 'Vars' - for(int i=0; i<size; i++) { - Var* var = dynamic_cast<Var*>(m_sym_vec[i]); - if (var != NULL) { - if (var->existPair("chip_object")) { - if (var->existPair("no_chip_object")) { - // Do nothing - } else { - string template_hack = ""; - if (var->existPair("template_hack")) { - template_hack = var->lookupPair("template_hack"); - } - if (// var->getType()->existPair("cache") || var->getType()->existPair("tbe") || -// var->getType()->existPair("newtbe") || var->getType()->existPair("timer") || -// var->getType()->existPair("dir") || var->getType()->existPair("persistent") || -// var->getType()->existPair("filter") || var->existPair("trigger_queue") - var->existPair("no_vector")) { - sstr << " delete m_" << var->cIdent() << "_ptr;\n"; - } else if ((var->getType()->existPair("mover")) && (var->getMachine()->getIdent() == "L2Cache")) { - sstr << " if (RubyConfig::isL2CacheDNUCAMoverChip(m_id)) {" << endl; - sstr << " delete m_" << var->cIdent() << "_ptr;\n"; - sstr << " }\n"; - } else if (var->getType()->existPair("mover") && ((var->getMachine()->getIdent() == "L1Cache") || (var->getMachine()->getIdent() == "Collector"))) { - sstr << " m_" << var->cIdent() << "_ptr = NULL;" << endl; - } else if (!var->existPair("network")) { - // Normal Object - sstr << " for (int i = 0; i < RubyConfig::numberOf" << var->getMachine()->getIdent() - << "PerChip(m_id); i++) {" << endl; - sstr << " delete m_" << var->cIdent() << "_vec[i];\n"; - sstr << " }\n"; - } - } - } - } - } - - // Look at all 'Machines' - for(int i=0; i<size; i++) { - StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]); - if (machine != NULL) { - string ident = machine->getIdent() + "_Controller"; - sstr << " for (int i = 0; i < RubyConfig::numberOf" << machine->getIdent() - << "PerChip(m_id); i++) {" << endl; - sstr << " delete m_" << ident << "_vec[i];\n"; - sstr << " }\n"; - } - } - sstr << "}\n"; - - sstr << "\n"; - sstr << "void Chip::clearStats()\n"; - sstr << "{\n"; - - - // Look at all 'Machines' - for(int i=0; i<size; i++) { - StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]); - if (machine != NULL) { - string ident = machine->getIdent() + "_Controller"; - sstr << " " << ident << "::clearStats();\n"; - } - } - - sstr << "}\n"; - - sstr << "\n"; - sstr << "void Chip::printStats(ostream& out)\n"; - sstr << "{\n"; - sstr << " out << endl;\n"; - sstr << " out << \"Chip Stats\" << endl;\n"; - sstr << " out << \"----------\" << endl << endl;\n"; - - // Look at all 'Machines' - for(int i=0; i<size; i++) { - StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]); - if (machine != NULL) { - string ident = machine->getIdent() + "_Controller"; - sstr << " " << ident << "::dumpStats(out);\n"; - } - } - - sstr << "}" << endl; - sstr << endl; - sstr << "void Chip::printConfig(ostream& out)\n"; - sstr << "{\n"; - sstr << " out << \"Chip Config\" << endl;\n"; - sstr << " out << \"-----------\" << endl;\n"; - sstr << " out << \"Total_Chips: \" << RubyConfig::numberOfChips() << endl;\n"; - - // Look at all 'Vars' - for(int i=0; i<size; i++) { - Var* var = dynamic_cast<Var*>(m_sym_vec[i]); - if (var != NULL) { - if (var->existPair("chip_object")) { - if (var->existPair("no_chip_object")) { - // Do nothing - } else { - string template_hack = ""; - if (var->existPair("template_hack")) { - template_hack = var->lookupPair("template_hack"); - } - - if (!var->existPair("network") && (!var->getType()->existPair("primitive"))) { - // Normal Object - if (!var->getType()->existPair("non_obj") && (!var->getType()->isEnumeration())) { - if (var->existPair("no_vector")) { - sstr << " m_" << var->cIdent() << "_ptr->printConfig(out);\n"; - } else { - sstr << " out << \"\\n" << var->cIdent() << " numberPerChip: \" << RubyConfig::numberOf" << var->getMachine()->getIdent() - << "PerChip() << endl;\n"; - sstr << " m_" << var->cIdent() << "_vec[0]->printConfig(out);\n"; -// sstr << " for (int i = 0; i < RubyConfig::numberOf" << var->getMachine()->getIdent() -// << "PerChip(m_id); i++) {" << endl; -// sstr << " m_" << var->cIdent() << "_vec[i]->printConfig(out);\n"; -// sstr << " }\n"; - } - } - } - } - } - } - } - - sstr << " out << endl;\n"; - sstr << "}" << endl; - - sstr << endl; - sstr << "void Chip::print(ostream& out) const\n"; - sstr << "{\n"; - sstr << " out << \"Ruby Chip\" << endl;\n"; - sstr << "}" << endl; - - sstr << "#ifdef CHECK_COHERENCE" << endl; - sstr << endl; - sstr << "bool Chip::isBlockShared(const Address& addr) const" << endl; - sstr << "{" << endl; - - // Look at all 'Machines' - for(int i=0; i<size; i++) { - StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]); - if (machine != NULL) { - string ident = machine->getIdent() + "_Controller"; - sstr << " for (int i = 0; i < RubyConfig::numberOf" << machine->getIdent() - << "PerChip(m_id); i++) {" << endl; - sstr << " if (m_" << ident << "_vec[i]->" << machine->getIdent() << "_isBlockShared(addr)) {\n"; - sstr << " return true; \n"; - sstr << " }\n"; - sstr << " }\n"; - } - } - sstr << " return false;" << endl; - sstr << "}" << endl; - sstr << endl; - - sstr << endl; - sstr << "bool Chip::isBlockExclusive(const Address& addr) const" << endl; - sstr << "{" << endl; - - // Look at all 'Machines' - for(int i=0; i<size; i++) { - StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]); - if (machine != NULL) { - string ident = machine->getIdent() + "_Controller"; - sstr << " for (int i = 0; i < RubyConfig::numberOf" << machine->getIdent() - << "PerChip(m_id); i++) {" << endl; - sstr << " if (m_" << ident << "_vec[i]->" << machine->getIdent() << "_isBlockExclusive(addr)) {\n"; - sstr << " return true; \n"; - sstr << " }\n"; - sstr << " }\n"; - } - } - - sstr << " return false;" << endl; - sstr << "}" << endl; - sstr << endl; - - sstr << "#endif /* CHECK_COHERENCE */ " << endl; - - - sstr << endl; - sstr << "void Chip::dumpCaches(ostream& out) const" << endl; - sstr << "{" << endl; - - // Look at all 'Vars' - for(int i=0; i<size; i++) { - Var* var = dynamic_cast<Var*>(m_sym_vec[i]); - if (var != NULL) { - if (var->getType()->existPair("cache")){ // caches are partitioned one per controller instaniation - sstr << " for (int i = 0; i < RubyConfig::numberOf" << var->getMachine()->getIdent() - << "PerChip(m_id); i++) {" << endl; - sstr << " m_" << var->cIdent() << "_vec[i]->print(out);\n"; - sstr << " }\n"; - } - } - } - sstr << "}" << endl; - sstr << endl; - - // Function to dump cache tag and data information - sstr << "void Chip::dumpCacheData(ostream& out) const" << endl; - sstr << "{" << endl; - - // Look at all 'Vars' - for(int i=0; i<size; i++) { - Var* var = dynamic_cast<Var*>(m_sym_vec[i]); - if (var != NULL) { - if (var->getType()->existPair("cache")){ // caches are partitioned one per controller instaniation - sstr << " for (int i = 0; i < RubyConfig::numberOf" << var->getMachine()->getIdent() - << "PerChip(m_id); i++) {" << endl; - sstr << " m_" << var->cIdent() << "_vec[i]->printData(out);\n"; - sstr << " }\n"; - } - } - } - sstr << "}" << endl; - sstr << endl; - - sstr << "void Chip::recordCacheContents(CacheRecorder& tr) const" << endl; - sstr << "{" << endl; - - // Look at all 'Vars' - for(int i=0; i<size; i++) { - Var* var = dynamic_cast<Var*>(m_sym_vec[i]); - if (var != NULL) { - if (var->getType()->existPair("cache")){ // caches are partitioned one per controller instaniation - sstr << " for (int i = 0; i < RubyConfig::numberOf" << var->getMachine()->getIdent() - << "PerChip(m_id); i++) {" << endl; - sstr << " m_" << var->cIdent() << "_vec[i]->recordCacheContents(tr);\n"; - sstr << " }\n"; - } - } - } - sstr << "}" << endl; + sstr << endl; - conditionally_write_file(path + "/Chip.cc", sstr); + 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 diff --git a/src/mem/slicc/symbols/SymbolTable.hh b/src/mem/slicc/symbols/SymbolTable.hh index afd3f9443..90d3f48c3 100644 --- a/src/mem/slicc/symbols/SymbolTable.hh +++ b/src/mem/slicc/symbols/SymbolTable.hh @@ -91,7 +91,7 @@ public: private: // Private Methods void registerGlobalSym(string id, Symbol* sym_ptr); - void writeChipFiles(string path) const; + void writeControllerFactory(string path) const; // Private copy constructor and assignment operator SymbolTable(const SymbolTable& obj); diff --git a/src/mem/slicc/symbols/Type.cc b/src/mem/slicc/symbols/Type.cc index 0a3a7a3be..75f72af02 100644 --- a/src/mem/slicc/symbols/Type.cc +++ b/src/mem/slicc/symbols/Type.cc @@ -176,7 +176,7 @@ bool Type::enumAdd(string id, Map<string, string> pairs_map) } } -void Type::writeCFiles(string path) const +void Type::writeCFiles(string path) { if (isExternal()) { // Do nothing @@ -298,6 +298,13 @@ void Type::printTypeH(string path) const 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 @@ -499,9 +506,6 @@ void Type::printEnumH(string path) const out << endl; // Include all of the #includes needed out << "#include \"mem/ruby/common/Global.hh\"" << endl; - if (m_isMachineType) { - out << "#include \"mem/ruby/config/RubyConfig.hh\"" << endl << endl; - } out << endl; // Class definition @@ -543,9 +547,10 @@ void Type::printEnumH(string path) const // 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, NodeID chipID);" << 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]; @@ -577,6 +582,14 @@ void Type::printEnumC(string path) const out << endl; out << "#include \"mem/protocol/" << type_name << ".hh\"" << endl; + if (m_isMachineType) { + out << "#include \"mem/ruby/config/RubyConfig.hh\"" << endl; + 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 @@ -637,7 +650,7 @@ void Type::printEnumC(string path) const 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 mem/ruby/common/NetDest.hh" << endl; + out << " * \\see NetDest.hh" << endl; out << " */" << endl; out << "int " << type_name << "_base_level(const " << type_name << "& obj)" << endl; out << "{" << endl; @@ -662,6 +675,30 @@ void Type::printEnumC(string path) const out << " }" << endl; out << "}" << endl; + out << "/** \\brief returns the machine type for each base vector index used by NetDest and RubyConfig" << 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; @@ -678,7 +715,7 @@ void Type::printEnumC(string path) const out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl; out << " return 0"; for ( int m = 0; m<MachineNames.size(); m++) { - out << "+RubyConfig::numberOf" << MachineNames[m] << "()"; + out << "+ " << MachineNames[m] << "_Controller::getNumControllers()"; } out << ";" << endl; MachineNames.insertAtBottom(m_enum_vec[i]); @@ -688,7 +725,7 @@ void Type::printEnumC(string path) const out << " case " << type_name << "_NUM:" << endl; out << " return 0"; for ( int m = 0; m<MachineNames.size(); m++) { - out << "+RubyConfig::numberOf" << MachineNames[m] << "()"; + out << "+ " << MachineNames[m] << "_Controller::getNumControllers()"; } out << ";" << endl; @@ -711,7 +748,7 @@ void Type::printEnumC(string path) const // For each field for( int i = 0; i<size; i++ ) { out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl; - out << " return RubyConfig::numberOf" << m_enum_vec[i] << "();" << endl; + out << " return " << m_enum_vec[i] << "_Controller::getNumControllers();" << endl; } // total num @@ -724,27 +761,28 @@ void Type::printEnumC(string path) const 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 << "_chip_count(const " << type_name << "& obj, NodeID chipID)" << 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 RubyConfig::numberOf" << m_enum_vec[i] << "PerChip(chipID);" << 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 << "_chip_count(const " << type_name << "& obj, int chip_id)" << 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 RubyConfig::getNumberOfControllersPerTypePerChip(MachineType_base_level(MachineType_" << m_enum_vec[i] << "), chip_id);" << 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; +// // 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; } diff --git a/src/mem/slicc/symbols/Type.hh b/src/mem/slicc/symbols/Type.hh index cd09c066f..07d661d3c 100644 --- a/src/mem/slicc/symbols/Type.hh +++ b/src/mem/slicc/symbols/Type.hh @@ -68,6 +68,7 @@ public: 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 @@ -92,7 +93,7 @@ public: bool enumExist(string id) const { return m_enum_map.exist(id); } // Write the C output files - void writeCFiles(string path) const; + void writeCFiles(string path) ; bool hasDefault() const { return existPair("default"); } string getDefault() const { return lookupPair("default"); } diff --git a/src/mem/slicc/symbols/Var.hh b/src/mem/slicc/symbols/Var.hh index 58e9f28e4..4cb504296 100644 --- a/src/mem/slicc/symbols/Var.hh +++ b/src/mem/slicc/symbols/Var.hh @@ -61,7 +61,7 @@ public: // Public Methods string cIdent() const { return m_c_id; } - void writeCFiles(string path) const {} + void writeCFiles(string path) {} string getCode() const { return m_code; } Type* getType() const { return m_type_ptr; } StateMachine* getMachine() const { return m_machine_ptr; } |