diff options
author | Polina Dudnik <pdudnik@gmail.com> | 2009-08-14 14:24:15 -0500 |
---|---|---|
committer | Polina Dudnik <pdudnik@gmail.com> | 2009-08-14 14:24:15 -0500 |
commit | de25decf37a7b0e2986da3345e8d4eb8b4a85fed (patch) | |
tree | 51f98b7f9f574ca8af1596a283503782d1347d72 /src/mem/slicc/symbols | |
parent | 4b924fd16cf64f242aa4832c13f38fd96c7c1fa0 (diff) | |
download | gem5-de25decf37a7b0e2986da3345e8d4eb8b4a85fed.tar.xz |
Multi-line RMW handling
Diffstat (limited to 'src/mem/slicc/symbols')
-rw-r--r-- | src/mem/slicc/symbols/StateMachine.cc | 105 |
1 files changed, 89 insertions, 16 deletions
diff --git a/src/mem/slicc/symbols/StateMachine.cc b/src/mem/slicc/symbols/StateMachine.cc index 7bc84ffe0..99c1953a1 100644 --- a/src/mem/slicc/symbols/StateMachine.cc +++ b/src/mem/slicc/symbols/StateMachine.cc @@ -290,6 +290,8 @@ void StateMachine::printControllerH(ostream& out, string component) out << " void print(ostream& out) const;" << endl; out << " void printConfig(ostream& out) const;" << endl; out << " void wakeup();" << endl; + out << " void set_atomic(Address addr);" << endl; + out << " void clear_atomic();" << endl; out << " void printStats(ostream& out) const { s_profiler.dumpStats(out); }" << endl; out << " void clearStats() { s_profiler.clearStats(); }" << endl; out << "private:" << endl; @@ -300,7 +302,11 @@ void StateMachine::printControllerH(ostream& out, string component) } if (strncmp(component.c_str(), "L1Cache", 7) == 0) { out << " bool servicing_atomic;" << endl; - out << " Address locked_read_request;" << endl; + out << " Address locked_read_request1;" << endl; + out << " Address locked_read_request2;" << endl; + out << " Address locked_read_request3;" << endl; + out << " Address locked_read_request4;" << endl; + out << " int read_counter;" << endl; } out << " int m_number_of_TBEs;" << endl; @@ -410,7 +416,11 @@ void StateMachine::printControllerC(ostream& out, string component) out << "{ " << endl; if (strncmp(component.c_str(), "L1Cache", 7) == 0) { out << " servicing_atomic = false;" << endl; - out << " locked_read_request = Address(-1);" << endl; + out << " locked_read_request1 = Address(-1);" << endl; + out << " locked_read_request2 = Address(-1);" << endl; + out << " locked_read_request3 = Address(-1);" << endl; + out << " locked_read_request4 = Address(-1);" << endl; + out << " read_counter = 0;" << endl; } out << " m_num_controllers++; " << endl; for(int i=0; i < numObjects(); i++) { @@ -717,7 +727,7 @@ void StateMachine::printControllerC(ostream& out, string component) string c_code_string = action.lookupPair("c_code"); // add here: - if (strncmp(component.c_str(), "L1Cache", 7) == 0) { + if (0/*strncmp(component.c_str(), "L1Cache", 7) == 0*/) { if (c_code_string.find("writeCallback") != string::npos) { string::size_type pos = c_code_string.find("(((*m_L1Cache_sequencer_ptr)).writeCallback"); assert(pos != string::npos); @@ -798,43 +808,67 @@ void StateMachine::printCWakeup(ostream& out, string component) 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) { \n \ - if (locked_read_request == Address(-1)) { \n \ - locked_read_request = addr; \n \ + if (locked_read_request1 == Address(-1)) { \n \ + assert(read_counter == 0); \n \ + locked_read_request1 = addr; \n \ + read_counter++; \n \ } \n \ - else if (addr == locked_read_request) { \n \ + else if (addr == locked_read_request1) { \n \ ; // do nothing \n\ } \n \ else { \n \ assert(0); // should never be here if servicing one request at a time \n\ } \n \ } \n \ - else if (addr != locked_read_request) { \n \ - // this is probably caused by shift optimizations \n \ - locked_read_request = addr; \n\ + else if (addr != locked_read_request1) { \n \ + if (locked_read_request2 == Address(-1)) { \n \ + assert(read_counter == 1); \n \ + locked_read_request2 = addr; \n \ + read_counter++; \n \ + } \n \ + else if (locked_read_request3 == Address(-1)) { \n \ + assert(read_counter == 2); \n \ + locked_read_request3 = addr; \n \ + read_counter++; \n \ + } \n \ + else if (locked_read_request4 == Address(-1)) { \n \ + assert(read_counter == 3); \n \ + locked_read_request4 = addr; \n \ + read_counter++; \n \ + } \n \ + else { \n \ + // reached limit of addresses that could be locked \n \ + // this can happen if there are multiple optimized consequtive shifts \n \ + assert(0); \n \ + } \n \ } \n \ } \n \ else { \n \ - if (locked_read_request != Address(-1)) { \n \ - locked_read_request = Address(-1); \n \ + // if an atomic is followed by non-atomic, reset -> shift optimization \n \ + // remove this and assert(0) once shifts are resolved \n \ + if (locked_read_request1 != Address(-1)) { \n \ + locked_read_request1 = Address(-1); \n \ + locked_read_request2 = Address(-1); \n \ + locked_read_request3 = Address(-1); \n \ + locked_read_request4 = Address(-1); \n \ servicing_atomic = false; \n \ + read_counter = 0; \n \ } \n \ } \n \ - if (!postpone) { \n \ "; output.insert(pos, atomics_string); - string foo = "// Cannot do anything with this transition, go check next doable transition (mostly likely of next port)\n"; + /*string foo = "// Cannot do anything with this transition, go check next doable transition (mostly likely of next port)\n"; string::size_type next_pos = output.find(foo, pos); next_pos = next_pos + foo.length(); assert(next_pos != string::npos); string complete = " }\n"; - output.insert(next_pos, complete); + output.insert(next_pos, complete);*/ //out << port->lookupPair("c_code_in_port"); out << output; out << endl; @@ -849,7 +883,10 @@ void StateMachine::printCWakeup(ostream& out, string component) out << " if ((((*m_L1Cache_forwardToCache_ptr)).isReady())) {" << endl; out << " const RequestMsg* in_msg_ptr;" << endl; out << " in_msg_ptr = dynamic_cast<const RequestMsg*>(((*m_L1Cache_forwardToCache_ptr)).peek());" << endl; - out << " if ((servicing_atomic && locked_read_request == ((*in_msg_ptr)).m_Address)) {" << endl; + out << " if ((servicing_atomic && (locked_read_request1 == ((*in_msg_ptr)).m_Address) || " << endl; + out << " (locked_read_request2 == ((*in_msg_ptr)).m_Address) || (locked_read_request3 == ((*in_msg_ptr)).m_Address) || " << endl; + out << " (locked_read_request4 == ((*in_msg_ptr)).m_Address))) { " << endl; + out << " postpone = true;" << endl; out << " }" << endl; out << " }" << endl; @@ -876,6 +913,42 @@ void StateMachine::printCWakeup(ostream& out, string component) // out << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl; out << "}" << endl; out << endl; + + + // tack on two more functions + if (strncmp(component.c_str(), "L1Cache", 7) == 0) { + out << "void " << component << "_Controller::set_atomic(Address addr)" << endl; + out << "{" << endl; + out << " if (!servicing_atomic) { " << endl; + out << " assert(addr == locked_read_request1); " << endl; + out << " servicing_atomic = true; " << endl; + out << " }" << endl; + out << "}" << endl; + out << "void " << component << "_Controller::clear_atomic()" << endl; + out << "{" << endl; + out << " assert(servicing_atomic); " << endl; + out << " read_counter--; " << endl; + out << " if (read_counter == 0) { " << endl; + out << " servicing_atomic = false; " << endl; + out << " locked_read_request1 = Address(-1); " << endl; + out << " locked_read_request2 = Address(-1); " << endl; + out << " locked_read_request3 = Address(-1); " << endl; + out << " locked_read_request4 = Address(-1); " << endl; + out << " } " << endl; + out << "}" << endl; + } + else { + out << "void " << component << "_Controller::set_atomic(Address addr)" << endl; + out << "{" << endl; + out << " assert(0); " << endl; + out << "}" << endl; + + out << "void " << component << "_Controller::clear_atomic()" << endl; + out << "{" << endl; + out << " assert(0); " << endl; + out << "}" << endl; + } + } void StateMachine::printCSwitch(ostream& out, string component) |