diff options
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; } |