Added atomics implementation which would work for MI_example
authorPolina Dudnik <pdudnik@gmail.com>
Mon, 13 Jul 2009 17:06:23 +0000 (12:06 -0500)
committerPolina Dudnik <pdudnik@gmail.com>
Mon, 13 Jul 2009 17:06:23 +0000 (12:06 -0500)
src/mem/slicc/symbols/StateMachine.cc

index f2a40d3d73a0cb93b5ffd306d9b39957ac14125d..896b37a91dfde0c46dfaf67ca0439215b823ebe8 100644 (file)
@@ -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;