summaryrefslogtreecommitdiff
path: root/src/mem/slicc
diff options
context:
space:
mode:
authorPolina Dudnik <pdudnik@gmail.com>2009-07-13 12:06:23 -0500
committerPolina Dudnik <pdudnik@gmail.com>2009-07-13 12:06:23 -0500
commit7a6bf67e47196fb9e6f3cac049203107381f7723 (patch)
tree8faa4decd4ba5c9cd41aa872e73d1de405c56944 /src/mem/slicc
parentc66af9f47400a7768de7cd6cb47fe757a601e445 (diff)
downloadgem5-7a6bf67e47196fb9e6f3cac049203107381f7723.tar.xz
Added atomics implementation which would work for MI_example
Diffstat (limited to 'src/mem/slicc')
-rw-r--r--src/mem/slicc/symbols/StateMachine.cc110
1 files changed, 105 insertions, 5 deletions
diff --git a/src/mem/slicc/symbols/StateMachine.cc b/src/mem/slicc/symbols/StateMachine.cc
index f2a40d3d7..896b37a91 100644
--- a/src/mem/slicc/symbols/StateMachine.cc
+++ b/src/mem/slicc/symbols/StateMachine.cc
@@ -759,6 +759,17 @@ void StateMachine::printCWakeup(ostream& out, string component)
out << "#include \"mem/protocol/Types.hh\"" << endl;
out << "#include \"mem/ruby/system/System.hh\"" << endl;
out << endl;
+ if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
+ out << "NodeID servicing_atomic = -1;" << endl;
+ out << endl;
+ out << "Address locked_read_request = Address(-1);" << endl;
+ out << endl;
+ out << "NodeID servicing_locked_read = -1;" << endl;
+ out << endl;
+ }
+ else {
+ cout << component << endl << flush;
+ }
out << "void " << component << "_Controller::wakeup()" << endl;
out << "{" << endl;
// out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,*this);" << endl;
@@ -775,15 +786,104 @@ void StateMachine::printCWakeup(ostream& out, string component)
out << " }" << endl;
// InPorts
- for(int i=0; i < m_in_ports.size(); i++) {
- const Var* port = m_in_ports[i];
+ //
+ // Find the position of the mandatory queue in the vector so that we can print it out first
+ int j = -1;
+ if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
+ for(int i=0; i < m_in_ports.size(); i++) {
+ const Var* port = m_in_ports[i];
+ assert(port->existPair("c_code_in_port"));
+ if (port->toString().find("mandatoryQueue_in") != string::npos) {
+ assert (j == -1);
+ j = i;
+ }
+ else {
+ cout << port->toString() << endl << flush;
+ }
+ }
+
+ assert(j != -1);
+
+ // print out the mandatory queue here
+ const Var* port = m_in_ports[j];
assert(port->existPair("c_code_in_port"));
- out << " // "
- << component << "InPort " << port->toString()
+ out << " // "
+ << component << "InPort " << port->toString()
<< endl;
- out << port->lookupPair("c_code_in_port");
+ string output = port->lookupPair("c_code_in_port");
+ string::size_type pos = output.find("TransitionResult result = doTransition((L1Cache_mandatory_request_type_to_event(((*in_msg_ptr)).m_Type)), L1Cache_getState(addr), addr);");
+ assert(pos != string::npos);
+ string atomics_string = "\n \
+ bool postpone = false; \n \
+ if ((((*in_msg_ptr)).m_Type) == CacheRequestType_ATOMIC) { \n \
+ if (servicing_atomic == -1) { \n \
+ if (locked_read_request == Address(-1) && (servicing_locked_read == -1)) { \n \
+ assert(addr != Address(-1)); \n \
+ locked_read_request = addr; \n \
+ servicing_locked_read = m_version; \n \
+ } \n \
+ else if ((addr == locked_read_request) && (servicing_locked_read == m_version)) { \n \
+ assert (servicing_atomic == -1); \n \
+ servicing_atomic = m_version; \n \
+ } \n \
+ else { \n \
+ postpone = true; \n \
+ g_eventQueue_ptr->scheduleEvent(this, 1); \n \
+ } \n \
+ } \n \
+ else { \n \
+ postpone = true; \n \
+ g_eventQueue_ptr->scheduleEvent(this, 1); \n \
+ } \n \
+ } \n \
+ if (servicing_atomic == m_version) { \n \
+ servicing_atomic = -1; \n \
+ locked_read_request = Address(-1); \n \
+ servicing_locked_read = -1; \n \
+ } \n \
+ if (!postpone) { \n \
+ ";
+
+
+
+ output.insert(pos, atomics_string);
+ string::size_type next_pos = output.find("// Cannot do anything with this transition, go check next doable transition (mostly likely of next port)", pos);
+ assert(next_pos != string::npos);
+ string complete = "\n}";
+ output.insert(next_pos, complete);
+ //out << port->lookupPair("c_code_in_port");
+ out << output;
out << endl;
}
+ for(int i=0; i < m_in_ports.size(); i++) {
+ const Var* port = m_in_ports[i];
+ // don't print out mandatory queue twice
+ if (i != j) {
+ if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
+ if (port->toString().find("forwardRequestNetwork_in") != string::npos) {
+ out << "if (servicing_atomic != m_version && servicing_locked_read != m_version) {" << endl;
+ }
+ else if (port->toString().find("responseNetwork_in") != string::npos) {
+ out << "// NOTE: this will only work if the WB_ACK always comes before issuing a request for which this line was replaced" << endl;
+ out << "if (servicing_atomic == -1 || servicing_atomic == m_version) {" << endl;
+ }
+ }
+ assert(port->existPair("c_code_in_port"));
+ out << " // "
+ << component << "InPort " << port->toString()
+ << endl;
+ out << port->lookupPair("c_code_in_port");
+ if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
+ if (port->toString().find("forwardRequestNetwork_in") != string::npos) {
+ out << "}" << endl;
+ }
+ else if (port->toString().find("responseNetwork_in") != string::npos) {
+ out << "}" << endl;
+ }
+ }
+ out << endl;
+ }
+ }
out << " break; // If we got this far, we have nothing left todo" << endl;
out << " }" << endl;