Matthew Poremba has uploaded this change for review. ( https://gem5-review.googlesource.com/8301

Change subject: ruby: Replace SLICC queueMemory calls with enqueue
......................................................................

ruby: Replace SLICC queueMemory calls with enqueue

Calls to queueMemoryRead and queueMemoryWrite do not consider the size
of the queue between ruby directories and DRAMCtrl which causes infinite
buffering in the queued port between the two. This adds a MessageBuffer
in between which uses enqueues in SLICC and is therefore size checked
before any SLICC transaction pushing to the buffer can occur, removing
the infinite buffering between the two.

Change-Id: I655b157be29e71abf06c7a6a8c1ef9c738e1ca54
---
M configs/ruby/GPU_RfO.py
M configs/ruby/GPU_VIPER.py
M configs/ruby/GPU_VIPER_Baseline.py
M configs/ruby/GPU_VIPER_Region.py
M configs/ruby/MESI_Two_Level.py
M configs/ruby/MI_example.py
M configs/ruby/MOESI_CMP_directory.py
M configs/ruby/MOESI_CMP_token.py
M configs/ruby/MOESI_hammer.py
M src/mem/protocol/MESI_Two_Level-dir.sm
M src/mem/protocol/MI_example-dir.sm
M src/mem/protocol/MOESI_AMD_Base-Region-dir.sm
M src/mem/protocol/MOESI_AMD_Base-dir.sm
M src/mem/protocol/MOESI_AMD_Base-probeFilter.sm
M src/mem/protocol/MOESI_CMP_directory-dir.sm
M src/mem/protocol/MOESI_CMP_token-dir.sm
M src/mem/protocol/MOESI_hammer-dir.sm
M src/mem/protocol/RubySlicc_Defines.sm
M src/mem/protocol/RubySlicc_MemControl.sm
M src/mem/ruby/slicc_interface/AbstractController.cc
M src/mem/ruby/slicc_interface/AbstractController.hh
M src/mem/slicc/symbols/StateMachine.py
22 files changed, 408 insertions(+), 160 deletions(-)



diff --git a/configs/ruby/GPU_RfO.py b/configs/ruby/GPU_RfO.py
index f900a48..728bddb 100644
--- a/configs/ruby/GPU_RfO.py
+++ b/configs/ruby/GPU_RfO.py
@@ -504,6 +504,7 @@

         dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
         dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
+        dir_cntrl.requestToMemory = MessageBuffer()
         dir_cntrl.responseFromMemory = MessageBuffer()

         exec("system.dir_cntrl%d = dir_cntrl" % i)
diff --git a/configs/ruby/GPU_VIPER.py b/configs/ruby/GPU_VIPER.py
index 36ef9f5..74d4b50 100644
--- a/configs/ruby/GPU_VIPER.py
+++ b/configs/ruby/GPU_VIPER.py
@@ -458,6 +458,7 @@

         dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
         dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
+        dir_cntrl.requestToMemory = MessageBuffer()
         dir_cntrl.responseFromMemory = MessageBuffer()

         exec("ruby_system.dir_cntrl%d = dir_cntrl" % i)
diff --git a/configs/ruby/GPU_VIPER_Baseline.py b/configs/ruby/GPU_VIPER_Baseline.py
index df3c60a..a13a482 100644
--- a/configs/ruby/GPU_VIPER_Baseline.py
+++ b/configs/ruby/GPU_VIPER_Baseline.py
@@ -436,6 +436,7 @@

         dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
         dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
+        dir_cntrl.requestToMemory = MessageBuffer()
         dir_cntrl.responseFromMemory = MessageBuffer()

         exec("system.dir_cntrl%d = dir_cntrl" % i)
diff --git a/configs/ruby/GPU_VIPER_Region.py b/configs/ruby/GPU_VIPER_Region.py
index 239624d..96316a6 100644
--- a/configs/ruby/GPU_VIPER_Region.py
+++ b/configs/ruby/GPU_VIPER_Region.py
@@ -715,6 +715,7 @@

     dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
     dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
+    dir_cntrl.requestToMemory = MessageBuffer()
     dir_cntrl.responseFromMemory = MessageBuffer()

     exec("system.dir_cntrl%d = dir_cntrl" % i)
diff --git a/configs/ruby/MESI_Two_Level.py b/configs/ruby/MESI_Two_Level.py
index 844c62a..921858b 100644
--- a/configs/ruby/MESI_Two_Level.py
+++ b/configs/ruby/MESI_Two_Level.py
@@ -183,6 +183,7 @@
         dir_cntrl.responseToDir.slave = ruby_system.network.master
         dir_cntrl.responseFromDir = MessageBuffer()
         dir_cntrl.responseFromDir.master = ruby_system.network.slave
+        dir_cntrl.requestToMemory = MessageBuffer()
         dir_cntrl.responseFromMemory = MessageBuffer()


diff --git a/configs/ruby/MI_example.py b/configs/ruby/MI_example.py
index eb881e5..ed0eedc 100644
--- a/configs/ruby/MI_example.py
+++ b/configs/ruby/MI_example.py
@@ -140,6 +140,7 @@
         dir_cntrl.dmaResponseFromDir.master = ruby_system.network.slave
         dir_cntrl.forwardFromDir = MessageBuffer()
         dir_cntrl.forwardFromDir.master = ruby_system.network.slave
+        dir_cntrl.requestToMemory = MessageBuffer()
         dir_cntrl.responseFromMemory = MessageBuffer()


diff --git a/configs/ruby/MOESI_CMP_directory.py b/configs/ruby/MOESI_CMP_directory.py
index cbb061d..ec66d06 100644
--- a/configs/ruby/MOESI_CMP_directory.py
+++ b/configs/ruby/MOESI_CMP_directory.py
@@ -177,6 +177,7 @@
         dir_cntrl.responseFromDir.master = ruby_system.network.slave
         dir_cntrl.forwardFromDir = MessageBuffer()
         dir_cntrl.forwardFromDir.master = ruby_system.network.slave
+        dir_cntrl.requestToMemory = MessageBuffer()
         dir_cntrl.responseFromMemory = MessageBuffer()


diff --git a/configs/ruby/MOESI_CMP_token.py b/configs/ruby/MOESI_CMP_token.py
index 7c98719..bb98146 100644
--- a/configs/ruby/MOESI_CMP_token.py
+++ b/configs/ruby/MOESI_CMP_token.py
@@ -212,6 +212,7 @@
         dir_cntrl.persistentFromDir.master = ruby_system.network.slave
         dir_cntrl.dmaResponseFromDir = MessageBuffer(ordered = True)
         dir_cntrl.dmaResponseFromDir.master = ruby_system.network.slave
+        dir_cntrl.requestToMemory = MessageBuffer()
         dir_cntrl.responseFromMemory = MessageBuffer()


diff --git a/configs/ruby/MOESI_hammer.py b/configs/ruby/MOESI_hammer.py
index 9f615f9..81dbd8a 100644
--- a/configs/ruby/MOESI_hammer.py
+++ b/configs/ruby/MOESI_hammer.py
@@ -203,6 +203,7 @@
         dir_cntrl.requestToDir.slave = ruby_system.network.master
         dir_cntrl.dmaRequestToDir = MessageBuffer(ordered = True)
         dir_cntrl.dmaRequestToDir.slave = ruby_system.network.master
+        dir_cntrl.requestToMemory = MessageBuffer()
         dir_cntrl.responseFromMemory = MessageBuffer()


diff --git a/src/mem/protocol/MESI_Two_Level-dir.sm b/src/mem/protocol/MESI_Two_Level-dir.sm
index 991de5a..56606a6 100644
--- a/src/mem/protocol/MESI_Two_Level-dir.sm
+++ b/src/mem/protocol/MESI_Two_Level-dir.sm
@@ -38,6 +38,7 @@
    MessageBuffer * responseFromDir, network="To", virtual_network="1",
         vnet_type="response";

+   MessageBuffer * requestToMemory;
    MessageBuffer * responseFromMemory;
 {
   // STATES
@@ -189,6 +190,7 @@

   // ** OUT_PORTS **
   out_port(responseNetwork_out, ResponseMsg, responseFromDir);
+  out_port(memQueue_out, MemoryMsg, requestToMemory);

   // ** IN_PORTS **

@@ -306,21 +308,39 @@

action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
     peek(requestNetwork_in, RequestMsg) {
-      queueMemoryRead(in_msg.Requestor, address, to_mem_ctrl_latency);
+      enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_READ;
+        out_msg.Sender := in_msg.Requestor;
+        out_msg.MessageSize := MessageSizeType:Request_Control;
+        out_msg.Len := 0;
+      }
     }
   }

action(qw_queueMemoryWBRequest, "qw", desc="Queue off-chip writeback request") {
     peek(responseNetwork_in, ResponseMsg) {
-      queueMemoryWrite(in_msg.Sender, address, to_mem_ctrl_latency,
-                       in_msg.DataBlk);
+      enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_WB;
+        out_msg.Sender := in_msg.Sender;
+        out_msg.MessageSize := MessageSizeType:Writeback_Data;
+        out_msg.DataBlk := in_msg.DataBlk;
+        out_msg.Len := 0;
+      }
     }
   }

 //added by SS for dma
action(qf_queueMemoryFetchRequestDMA, "qfd", desc="Queue off-chip fetch request") {
     peek(requestNetwork_in, RequestMsg) {
-      queueMemoryRead(in_msg.Requestor, address, to_mem_ctrl_latency);
+      enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_READ;
+        out_msg.Sender := in_msg.Requestor;
+        out_msg.MessageSize := MessageSizeType:Request_Control;
+        out_msg.Len := 0;
+      }
     }
   }

@@ -344,8 +364,14 @@
   action(qw_queueMemoryWBRequest_partial, "qwp",
          desc="Queue off-chip writeback request") {
     peek(requestNetwork_in, RequestMsg) {
-      queueMemoryWritePartial(machineID, address, to_mem_ctrl_latency,
-                              in_msg.DataBlk, in_msg.Len);
+      enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_WB;
+        out_msg.Sender := machineID;
+        out_msg.MessageSize := MessageSizeType:Writeback_Data;
+        out_msg.DataBlk := in_msg.DataBlk;
+        out_msg.Len := in_msg.Len;
+      }
     }
   }

@@ -407,8 +433,14 @@
   action(qw_queueMemoryWBRequest_partialTBE, "qwt",
          desc="Queue off-chip writeback request") {
     peek(responseNetwork_in, ResponseMsg) {
-      queueMemoryWritePartial(in_msg.Sender, tbe.PhysicalAddress,
-                              to_mem_ctrl_latency, tbe.DataBlk, tbe.Len);
+      enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
+        out_msg.addr := tbe.PhysicalAddress;
+        out_msg.Type := MemoryRequestType:MEMORY_WB;
+        out_msg.Sender := in_msg.Sender;
+        out_msg.MessageSize := MessageSizeType:Writeback_Data;
+        out_msg.DataBlk := tbe.DataBlk;
+        out_msg.Len := tbe.Len;
+      }
     }
   }

diff --git a/src/mem/protocol/MI_example-dir.sm b/src/mem/protocol/MI_example-dir.sm
index e2d8342..e4696c4 100644
--- a/src/mem/protocol/MI_example-dir.sm
+++ b/src/mem/protocol/MI_example-dir.sm
@@ -43,6 +43,8 @@
             vnet_type="request";
       MessageBuffer * dmaRequestToDir, network="From", virtual_network="0",
             vnet_type="request";
+
+      MessageBuffer * requestToMemory;
       MessageBuffer * responseFromMemory;
 {
   // STATES
@@ -204,6 +206,7 @@
   out_port(responseNetwork_out, ResponseMsg, responseFromDir);
out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests
   out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
+  out_port(memQueue_out, MemoryMsg, requestToMemory);

   // ** IN_PORTS **
   in_port(dmaRequestQueue_in, DMARequestMsg, dmaRequestToDir) {
@@ -445,36 +448,64 @@

action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
     peek(requestQueue_in, RequestMsg) {
- queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
+      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_READ;
+        out_msg.Sender := in_msg.Requestor;
+        out_msg.MessageSize := MessageSizeType:Request_Control;
+        out_msg.Len := 0;
+      }
     }
   }

action(qf_queueMemoryFetchRequestDMA, "qfd", desc="Queue off-chip fetch request") {
     peek(dmaRequestQueue_in, DMARequestMsg) {
- queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
+      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_READ;
+        out_msg.Sender := in_msg.Requestor;
+        out_msg.MessageSize := MessageSizeType:Request_Control;
+        out_msg.Len := 0;
+      }
     }
   }

action(qw_queueMemoryWBRequest_partial, "qwp", desc="Queue off-chip writeback request") {
     peek(dmaRequestQueue_in, DMARequestMsg) {
-      queueMemoryWritePartial(in_msg.Requestor, address,
-                              to_memory_controller_latency, in_msg.DataBlk,
-                              in_msg.Len);
+      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_WB;
+        out_msg.Sender := in_msg.Requestor;
+        out_msg.MessageSize := MessageSizeType:Writeback_Data;
+        out_msg.DataBlk := in_msg.DataBlk;
+        out_msg.Len := in_msg.Len;
+      }
     }
   }

action(qw_queueMemoryWBRequest_partialTBE, "qwt", desc="Queue off-chip writeback request") {
     peek(requestQueue_in, RequestMsg) {
-      queueMemoryWritePartial(in_msg.Requestor, address,
-                              to_memory_controller_latency, tbe.DataBlk,
-                              tbe.Len);
+      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_WB;
+        out_msg.Sender := in_msg.Requestor;
+        out_msg.MessageSize := MessageSizeType:Writeback_Data;
+        out_msg.DataBlk := tbe.DataBlk;
+        out_msg.Len := tbe.Len;
+      }
     }
   }

   action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") {
     peek(requestQueue_in, RequestMsg) {
- queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency,
-                       in_msg.DataBlk);
+      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_WB;
+        out_msg.Sender := in_msg.Requestor;
+        out_msg.MessageSize := MessageSizeType:Writeback_Data;
+        out_msg.DataBlk := in_msg.DataBlk;
+        out_msg.Len := 0;
+      }
     }
   }

diff --git a/src/mem/protocol/MOESI_AMD_Base-Region-dir.sm b/src/mem/protocol/MOESI_AMD_Base-Region-dir.sm
index 328e1a5..a7321ad 100644
--- a/src/mem/protocol/MOESI_AMD_Base-Region-dir.sm
+++ b/src/mem/protocol/MOESI_AMD_Base-Region-dir.sm
@@ -61,6 +61,8 @@

   MessageBuffer * triggerQueue;
   MessageBuffer * L3triggerQueue;
+
+  MessageBuffer * requestToMemory;
   MessageBuffer * responseFromMemory;
 {
   // STATES
@@ -319,6 +321,8 @@
   out_port(triggerQueue_out, TriggerMsg, triggerQueue);
   out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue);

+  out_port(memQueue_out, MemoryMsg, requestToMemory);
+
   // ** IN_PORTS **

   // Trigger Queue
@@ -841,7 +845,12 @@
         DPRINTF(RubySlicc, "L3 data is %s\n", entry.DataBlk);
         L3CacheMemory.deallocate(address);
       } else {
-        queueMemoryRead(machineID, address, to_memory_controller_latency);
+        enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+          out_msg.addr := address;
+          out_msg.Type := MemoryRequestType:MEMORY_READ;
+          out_msg.Sender := machineID;
+          out_msg.MessageSize := MessageSizeType:Request_Control;
+        }
       }
     }
   }
@@ -862,7 +871,12 @@
         DPRINTF(RubySlicc, "L3 data is %s\n", entry.DataBlk);
         L3CacheMemory.deallocate(address);
       } else {
-        queueMemoryRead(machineID, address, to_memory_controller_latency);
+        enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+          out_msg.addr := address;
+          out_msg.Type := MemoryRequestType:MEMORY_READ;
+          out_msg.Sender := machineID;
+          out_msg.MessageSize := MessageSizeType:Request_Control;
+        }
       }
     }
   }
@@ -1254,8 +1268,13 @@
           Addr victim := L3CacheMemory.cacheProbe(address);
           CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
L3CacheMemory.lookup(victim));
-          queueMemoryWrite(machineID, victim, to_memory_controller_latency,
-                           victim_entry.DataBlk);
+          enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+            out_msg.addr := victim;
+            out_msg.Type := MemoryRequestType:MEMORY_WB;
+            out_msg.Sender := machineID;
+            out_msg.MessageSize := MessageSizeType:Writeback_Data;
+            out_msg.DataBlk := victim_entry.DataBlk;
+          }
           L3CacheMemory.deallocate(victim);
         }
         assert(L3CacheMemory.cacheAvail(address));
@@ -1279,8 +1298,13 @@
           Addr victim := L3CacheMemory.cacheProbe(address);
           CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
L3CacheMemory.lookup(victim));
-          queueMemoryWrite(machineID, victim, to_memory_controller_latency,
-                           victim_entry.DataBlk);
+          enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+            out_msg.addr := victim;
+            out_msg.Type := MemoryRequestType:MEMORY_WB;
+            out_msg.Sender := machineID;
+            out_msg.MessageSize := MessageSizeType:Writeback_Data;
+            out_msg.DataBlk := victim_entry.DataBlk;
+          }
           L3CacheMemory.deallocate(victim);
         }
         assert(L3CacheMemory.cacheAvail(address));
@@ -1304,8 +1328,13 @@
           Addr victim := L3CacheMemory.cacheProbe(address);
           CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
L3CacheMemory.lookup(victim));
-          queueMemoryWrite(machineID, victim, to_memory_controller_latency,
-                           victim_entry.DataBlk);
+          enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+            out_msg.addr := victim;
+            out_msg.Type := MemoryRequestType:MEMORY_WB;
+            out_msg.Sender := machineID;
+            out_msg.MessageSize := MessageSizeType:Writeback_Data;
+            out_msg.DataBlk := victim_entry.DataBlk;
+          }
           L3CacheMemory.deallocate(victim);
         }
         assert(L3CacheMemory.cacheAvail(address));
@@ -1330,8 +1359,13 @@
             Addr victim := L3CacheMemory.cacheProbe(address);
             CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
L3CacheMemory.lookup(victim)); - queueMemoryWrite(machineID, victim, to_memory_controller_latency,
-                             victim_entry.DataBlk);
+ enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+              out_msg.addr := victim;
+              out_msg.Type := MemoryRequestType:MEMORY_WB;
+              out_msg.Sender := machineID;
+              out_msg.MessageSize := MessageSizeType:Writeback_Data;
+              out_msg.DataBlk := victim_entry.DataBlk;
+            }
             L3CacheMemory.deallocate(victim);
           }
           assert(L3CacheMemory.cacheAvail(address));
diff --git a/src/mem/protocol/MOESI_AMD_Base-dir.sm b/src/mem/protocol/MOESI_AMD_Base-dir.sm
index 52cefda..7e26abd 100644
--- a/src/mem/protocol/MOESI_AMD_Base-dir.sm
+++ b/src/mem/protocol/MOESI_AMD_Base-dir.sm
@@ -54,6 +54,8 @@

   MessageBuffer * triggerQueue;
   MessageBuffer * L3triggerQueue;
+
+  MessageBuffer * requestToMemory;
   MessageBuffer * responseFromMemory;
 {
   // STATES
@@ -272,6 +274,8 @@
   out_port(triggerQueue_out, TriggerMsg, triggerQueue);
   out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue);

+  out_port(memQueue_out, MemoryMsg, requestToMemory);
+
   // ** IN_PORTS **

   // Trigger Queue
@@ -518,8 +522,13 @@

   action(l_queueMemWBReq, "lq", desc="Write WB data to memory") {
     peek(responseNetwork_in, ResponseMsg) {
-      queueMemoryWrite(machineID, address, to_memory_controller_latency,
-                       in_msg.DataBlk);
+      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_WB;
+        out_msg.Sender := machineID;
+        out_msg.MessageSize := MessageSizeType:Writeback_Data;
+        out_msg.DataBlk := in_msg.DataBlk;
+      }
     }
   }

@@ -540,7 +549,12 @@
         tbe.MemData := true;
         L3CacheMemory.deallocate(address);
       } else {
-        queueMemoryRead(machineID, address, to_memory_controller_latency);
+        enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+          out_msg.addr := address;
+          out_msg.Type := MemoryRequestType:MEMORY_READ;
+          out_msg.Sender := machineID;
+          out_msg.MessageSize := MessageSizeType:Request_Control;
+        }
       }
     }
   }
@@ -797,8 +811,13 @@
           Addr victim := L3CacheMemory.cacheProbe(address);
           CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
L3CacheMemory.lookup(victim));
-          queueMemoryWrite(machineID, victim, to_memory_controller_latency,
-                           victim_entry.DataBlk);
+          enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+            out_msg.addr := victim;
+            out_msg.Type := MemoryRequestType:MEMORY_WB;
+            out_msg.Sender := machineID;
+            out_msg.MessageSize := MessageSizeType:Writeback_Data;
+            out_msg.DataBlk := victim_entry.DataBlk;
+          }
           L3CacheMemory.deallocate(victim);
         }
         assert(L3CacheMemory.cacheAvail(address));
@@ -823,8 +842,13 @@
           Addr victim := L3CacheMemory.cacheProbe(address);
           CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
L3CacheMemory.lookup(victim));
-          queueMemoryWrite(machineID, victim, to_memory_controller_latency,
-                           victim_entry.DataBlk);
+          enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+            out_msg.addr := victim;
+            out_msg.Type := MemoryRequestType:MEMORY_WB;
+            out_msg.Sender := machineID;
+            out_msg.MessageSize := MessageSizeType:Writeback_Data;
+            out_msg.DataBlk := victim_entry.DataBlk;
+          }
           L3CacheMemory.deallocate(victim);
         }
         assert(L3CacheMemory.cacheAvail(address));
diff --git a/src/mem/protocol/MOESI_AMD_Base-probeFilter.sm b/src/mem/protocol/MOESI_AMD_Base-probeFilter.sm
index 88d73d1..a0b496f 100644
--- a/src/mem/protocol/MOESI_AMD_Base-probeFilter.sm
+++ b/src/mem/protocol/MOESI_AMD_Base-probeFilter.sm
@@ -66,6 +66,8 @@

   MessageBuffer * triggerQueue, ordered="true";
   MessageBuffer * L3triggerQueue, ordered="true";
+
+  MessageBuffer * requestToMemory;
   MessageBuffer * responseFromMemory;
 {
   // STATES
@@ -351,6 +353,8 @@
   out_port(triggerQueue_out, TriggerMsg, triggerQueue);
   out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue);

+  out_port(memQueue_out, MemoryMsg, requestToMemory);
+
   // ** IN_PORTS **

   // Trigger Queue
@@ -607,8 +611,13 @@

   action(l_queueMemWBReq, "lq", desc="Write WB data to memory") {
     peek(responseNetwork_in, ResponseMsg) {
-      queueMemoryWrite(machineID, address, to_memory_controller_latency,
-                       in_msg.DataBlk);
+      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_WB;
+        out_msg.Sender := machineID;
+        out_msg.MessageSize := MessageSizeType:Writeback_Data;
+        out_msg.DataBlk := in_msg.DataBlk;
+      }
     }
   }

@@ -627,7 +636,12 @@
         tbe.MemData := true;
         L3CacheMemory.deallocate(address);
       } else {
-        queueMemoryRead(machineID, address, to_memory_controller_latency);
+        enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+          out_msg.addr := address;
+          out_msg.Type := MemoryRequestType:MEMORY_READ;
+          out_msg.Sender := machineID;
+          out_msg.MessageSize := MessageSizeType:Request_Control;
+        }
       }
     }
   }
@@ -944,8 +958,13 @@
           Addr victim := L3CacheMemory.cacheProbe(address);
           CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
L3CacheMemory.lookup(victim));
-          queueMemoryWrite(machineID, victim, to_memory_controller_latency,
-                           victim_entry.DataBlk);
+          enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+            out_msg.addr := victim;
+            out_msg.Type := MemoryRequestType:MEMORY_WB;
+            out_msg.Sender := machineID;
+            out_msg.MessageSize := MessageSizeType:Writeback_Data;
+            out_msg.DataBlk := victim_entry.DataBlk;
+          }
           L3CacheMemory.deallocate(victim);
         }
         assert(L3CacheMemory.cacheAvail(address));
@@ -970,8 +989,13 @@
           Addr victim := L3CacheMemory.cacheProbe(address);
           CacheEntry victim_entry := static_cast(CacheEntry, "pointer",
L3CacheMemory.lookup(victim));
-          queueMemoryWrite(machineID, victim, to_memory_controller_latency,
-                           victim_entry.DataBlk);
+          enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+            out_msg.addr := victim;
+            out_msg.Type := MemoryRequestType:MEMORY_WB;
+            out_msg.Sender := machineID;
+            out_msg.MessageSize := MessageSizeType:Writeback_Data;
+            out_msg.DataBlk := victim_entry.DataBlk;
+          }
           L3CacheMemory.deallocate(victim);
         }
         assert(L3CacheMemory.cacheAvail(address));
diff --git a/src/mem/protocol/MOESI_CMP_directory-dir.sm b/src/mem/protocol/MOESI_CMP_directory-dir.sm
index 9b73a2b..33d5f9e 100644
--- a/src/mem/protocol/MOESI_CMP_directory-dir.sm
+++ b/src/mem/protocol/MOESI_CMP_directory-dir.sm
@@ -42,6 +42,7 @@
    MessageBuffer * responseFromDir, network="To", virtual_network="2",
         vnet_type="response";  // Dir -> mod-L2 bank

+   MessageBuffer * requestToMemory;
    MessageBuffer * responseFromMemory;
 {
   // STATES
@@ -226,6 +227,7 @@
   // ** OUT_PORTS **
   out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
   out_port(responseNetwork_out, ResponseMsg, responseFromDir);
+  out_port(memQueue_out, MemoryMsg, requestToMemory);

   // ** IN_PORTS **

@@ -468,18 +470,36 @@

action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
     peek(requestQueue_in, RequestMsg) {
- queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
+      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_READ;
+        out_msg.Sender := in_msg.Requestor;
+        out_msg.MessageSize := MessageSizeType:Request_Control;
+        out_msg.Len := 0;
+      }
     }
   }

action(qw_queueMemoryWBRequest, "qw", desc="Queue off-chip writeback request") {
     peek(unblockNetwork_in, ResponseMsg) {
       if (is_valid(tbe)) {
- queueMemoryWrite(tbe.Requestor, address, to_memory_controller_latency,
-                         in_msg.DataBlk);
+        enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+          out_msg.addr := address;
+          out_msg.Type := MemoryRequestType:MEMORY_WB;
+          out_msg.Sender := tbe.Requestor;
+          out_msg.MessageSize := MessageSizeType:Writeback_Data;
+          out_msg.DataBlk := in_msg.DataBlk;
+          out_msg.Len := 0;
+        }
       } else {
- queueMemoryWrite(in_msg.Sender, address, to_memory_controller_latency,
-                         in_msg.DataBlk);
+        enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+          out_msg.addr := address;
+          out_msg.Type := MemoryRequestType:MEMORY_WB;
+          out_msg.Sender := in_msg.Sender;
+          out_msg.MessageSize := MessageSizeType:Writeback_Data;
+          out_msg.DataBlk := in_msg.DataBlk;
+          out_msg.Len := 0;
+        }
       }
     }
   }
@@ -490,15 +510,27 @@
       DataBlock DataBlk := in_msg.DataBlk;
       DataBlk.copyPartial(tbe.DataBlk, getOffset(tbe.PhysicalAddress),
                           tbe.Len);
- queueMemoryWrite(tbe.Requestor, address, to_memory_controller_latency,
-                       DataBlk);
+      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_WB;
+        out_msg.Sender := tbe.Requestor;
+        out_msg.MessageSize := MessageSizeType:Writeback_Data;
+        out_msg.DataBlk := DataBlk;
+        out_msg.Len := 0;
+      }
     }
   }

action(qw_queueMemoryWBRequest2, "/qw", desc="Queue off-chip writeback request") {
     peek(requestQueue_in, RequestMsg) {
- queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency,
-                       in_msg.DataBlk);
+      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_WB;
+        out_msg.Sender := in_msg.Requestor;
+        out_msg.MessageSize := MessageSizeType:Writeback_Data;
+        out_msg.DataBlk := in_msg.DataBlk;
+        out_msg.Len := 0;
+      }
     }
   }

diff --git a/src/mem/protocol/MOESI_CMP_token-dir.sm b/src/mem/protocol/MOESI_CMP_token-dir.sm
index b9b65b5..362bebd 100644
--- a/src/mem/protocol/MOESI_CMP_token-dir.sm
+++ b/src/mem/protocol/MOESI_CMP_token-dir.sm
@@ -61,6 +61,7 @@
    MessageBuffer * dmaRequestToDir, network="From", virtual_network="0",
         vnet_type="request";

+   MessageBuffer * requestToMemory;
    MessageBuffer * responseFromMemory;
 {
   // STATES
@@ -276,6 +277,7 @@
   out_port(persistentNetwork_out, PersistentMsg, persistentFromDir);
   out_port(requestNetwork_out, RequestMsg, requestFromDir);
   out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
+  out_port(memQueue_out, MemoryMsg, requestToMemory);

   // ** IN_PORTS **
   // off-chip memory request/response is done
@@ -656,39 +658,73 @@

action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
     peek(requestNetwork_in, RequestMsg) {
- queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
+      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_READ;
+        out_msg.Sender := in_msg.Requestor;
+        out_msg.MessageSize := MessageSizeType:Request_Control;
+        out_msg.Len := 0;
+      }
     }
   }

action(qp_queueMemoryForPersistent, "qp", desc="Queue off-chip fetch request") {
-    queueMemoryRead(persistentTable.findSmallest(address), address,
-                    to_memory_controller_latency);
+    enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+      out_msg.addr := address;
+      out_msg.Type := MemoryRequestType:MEMORY_READ;
+      out_msg.Sender := persistentTable.findSmallest(address);
+      out_msg.MessageSize := MessageSizeType:Request_Control;
+      out_msg.Len := 0;
+    }
   }

   action(fd_memoryDma, "fd", desc="Queue off-chip fetch request") {
     peek(dmaRequestQueue_in, DMARequestMsg) {
- queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
+      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_READ;
+        out_msg.Sender := in_msg.Requestor;
+        out_msg.MessageSize := MessageSizeType:Request_Control;
+        out_msg.Len := 0;
+      }
     }
   }

   action(lq_queueMemoryWbRequest, "lq", desc="Write data to memory") {
     peek(responseNetwork_in, ResponseMsg) {
- queueMemoryWrite(in_msg.Sender, address, to_memory_controller_latency,
-                       in_msg.DataBlk);
+      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_WB;
+        out_msg.Sender := in_msg.Sender;
+        out_msg.MessageSize := MessageSizeType:Writeback_Data;
+        out_msg.DataBlk := in_msg.DataBlk;
+        out_msg.Len := 0;
+      }
     }
   }

action(ld_queueMemoryDmaWriteFromTbe, "ld", desc="Write DMA data to memory") {
-    queueMemoryWritePartial(tbe.DmaRequestor, address,
-                            to_memory_controller_latency, tbe.DataBlk,
-                            tbe.Len);
+    enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+      out_msg.addr := address;
+      out_msg.Type := MemoryRequestType:MEMORY_WB;
+      out_msg.Sender := tbe.DmaRequestor;
+      out_msg.MessageSize := MessageSizeType:Writeback_Data;
+      out_msg.DataBlk := tbe.DataBlk;
+      out_msg.Len := tbe.Len;
+    }
   }

   action(lr_queueMemoryDmaReadWriteback, "lr",
          desc="Write DMA data from read to memory") {
     peek(responseNetwork_in, ResponseMsg) {
-      queueMemoryWrite(machineID, address, to_memory_controller_latency,
-                       in_msg.DataBlk);
+      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_WB;
+        out_msg.Sender := machineID;
+        out_msg.MessageSize := MessageSizeType:Writeback_Data;
+        out_msg.DataBlk := in_msg.DataBlk;
+        out_msg.Len := 0;
+      }
     }
   }

diff --git a/src/mem/protocol/MOESI_hammer-dir.sm b/src/mem/protocol/MOESI_hammer-dir.sm
index 42522c7..3699031 100644
--- a/src/mem/protocol/MOESI_hammer-dir.sm
+++ b/src/mem/protocol/MOESI_hammer-dir.sm
@@ -66,6 +66,7 @@
             vnet_type="request";

       MessageBuffer * triggerQueue;
+      MessageBuffer * requestToMemory;
       MessageBuffer * responseFromMemory;
 {
   // STATES
@@ -307,6 +308,7 @@
   // ** OUT_PORTS **
out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests
   out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
+  out_port(memQueue_out, MemoryMsg, requestToMemory);
   out_port(responseNetwork_out, ResponseMsg, responseFromDir);
   out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
   out_port(triggerQueue_out, TriggerMsg, triggerQueue);
@@ -848,13 +850,25 @@

action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
     peek(requestQueue_in, RequestMsg) {
- queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
+      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_READ;
+        out_msg.Sender := in_msg.Requestor;
+        out_msg.MessageSize := MessageSizeType:Request_Control;
+        out_msg.Len := 0;
+      }
     }
   }

action(qd_queueMemoryRequestFromDmaRead, "qd", desc="Queue off-chip fetch request") {
     peek(dmaRequestQueue_in, DMARequestMsg) {
- queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
+      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_READ;
+        out_msg.Sender := in_msg.Requestor;
+        out_msg.MessageSize := MessageSizeType:Request_Control;
+        out_msg.Len := 0;
+      }
     }
   }

@@ -1208,21 +1222,38 @@

   action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") {
     peek(unblockNetwork_in, ResponseMsg) {
- queueMemoryWrite(in_msg.Sender, address, to_memory_controller_latency,
-                       in_msg.DataBlk);
+      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+        out_msg.addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_WB;
+        out_msg.Sender := in_msg.Sender;
+        out_msg.MessageSize := MessageSizeType:Writeback_Data;
+        out_msg.DataBlk := in_msg.DataBlk;
+        out_msg.Len := 0;
+      }
     }
   }

   action(ld_queueMemoryDmaWrite, "ld", desc="Write DMA data to memory") {
     assert(is_valid(tbe));
-    queueMemoryWritePartial(tbe.DmaRequestor, tbe.PhysicalAddress,
-                            to_memory_controller_latency, tbe.DmaDataBlk,
-                            tbe.Len);
+    enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+      out_msg.addr := tbe.PhysicalAddress;
+      out_msg.Type := MemoryRequestType:MEMORY_WB;
+      out_msg.Sender := tbe.DmaRequestor;
+      out_msg.MessageSize := MessageSizeType:Writeback_Data;
+      out_msg.DataBlk := tbe.DmaDataBlk;
+      out_msg.Len := tbe.Len;
+    }
   }

action(ly_queueMemoryWriteFromTBE, "ly", desc="Write data to memory from TBE") {
-    queueMemoryWrite(machineID, address, to_memory_controller_latency,
-                     tbe.DataBlk);
+    enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
+      out_msg.addr := address;
+      out_msg.Type := MemoryRequestType:MEMORY_WB;
+      out_msg.Sender := tbe.DmaRequestor;
+      out_msg.MessageSize := MessageSizeType:Writeback_Data;
+      out_msg.DataBlk := tbe.DataBlk;
+      out_msg.Len := 0;
+    }
   }

action(ll_checkIncomingWriteback, "\l", desc="Check PUTX/PUTO response message") { diff --git a/src/mem/protocol/RubySlicc_Defines.sm b/src/mem/protocol/RubySlicc_Defines.sm
index eb235f8..6ae3a6c 100644
--- a/src/mem/protocol/RubySlicc_Defines.sm
+++ b/src/mem/protocol/RubySlicc_Defines.sm
@@ -33,15 +33,6 @@
 Cycles recycle_latency;

 // Functions implemented in the AbstractController class for
-// making timing access to the memory maintained by the
-// memory controllers.
-void queueMemoryRead(MachineID id, Addr addr, Cycles latency);
-void queueMemoryWrite(MachineID id, Addr addr, Cycles latency,
-                      DataBlock block);
-void queueMemoryWritePartial(MachineID id, Addr addr, Cycles latency,
-                             DataBlock block, int size);
-
-// Functions implemented in the AbstractController class for
 // making functional access to the memory maintained by the
 // memory controllers.
 void functionalMemoryRead(Packet *pkt);
diff --git a/src/mem/protocol/RubySlicc_MemControl.sm b/src/mem/protocol/RubySlicc_MemControl.sm
index f211789..c8641d5 100644
--- a/src/mem/protocol/RubySlicc_MemControl.sm
+++ b/src/mem/protocol/RubySlicc_MemControl.sm
@@ -57,6 +57,8 @@
MachineID OriginalRequestorMachId, desc="What component originally requested";
   DataBlock DataBlk,            desc="Data to writeback";
   MessageSizeType MessageSize,  desc="size category of the message";
+  // For Len, the value 0 implies the whole data block is used.
+  int Len, default="0",         desc="Size of the memory request";
   // Not all fields used by all protocols:
   PrefetchBit Prefetch,         desc="Is this a prefetch request";
   bool ReadX,                   desc="Exclusive";
diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc b/src/mem/ruby/slicc_interface/AbstractController.cc
index b920ff7..2869f4b 100644
--- a/src/mem/ruby/slicc_interface/AbstractController.cc
+++ b/src/mem/ruby/slicc_interface/AbstractController.cc
@@ -75,6 +75,10 @@
         m_delayVCHistogram.push_back(new Stats::Histogram());
         m_delayVCHistogram[i]->init(10);
     }
+
+    if (getMemReqQueue()) {
+        getMemReqQueue()->setConsumer(this);
+    }
 }

 void
@@ -201,6 +205,61 @@
     }
 }

+bool
+AbstractController::serviceMemoryQueue(PacketPtr)
+{
+    assert(getMemReqQueue());
+    if (!getMemReqQueue()->isReady(clockEdge())) {
+        return false;
+    }
+
+    const MemoryMsg *mem_msg = (const MemoryMsg*)getMemReqQueue()->peek();
+    unsigned int req_size = RubySystem::getBlockSizeBytes();
+    if (mem_msg->m_Len > 0) {
+        req_size = mem_msg->m_Len;
+    }
+
+    RequestPtr req = new Request(mem_msg->m_addr, req_size, 0, m_masterId);
+    PacketPtr pkt;
+    if (mem_msg->getType() == MemoryRequestType_MEMORY_WB) {
+        pkt = Packet::createWrite(req);
+        uint8_t *newData = new uint8_t[req_size];
+        pkt->dataDynamic(newData);
+        int offset = getOffset(mem_msg->m_addr);
+        memcpy(newData, mem_msg->m_DataBlk.getData(offset, req_size),
+               req_size);
+    } else if (mem_msg->getType() == MemoryRequestType_MEMORY_READ) {
+        pkt = Packet::createRead(req);
+        uint8_t *newData = new uint8_t[req_size];
+        pkt->dataDynamic(newData);
+    } else {
+        panic("Unknown memory request type (%s) for addr %p",
+              MemoryRequestType_to_string(mem_msg->getType()),
+              mem_msg->m_addr);
+    }
+
+    SenderState *s = new SenderState(mem_msg->m_Sender);
+    pkt->pushSenderState(s);
+
+    if (RubySystem::getWarmupEnabled()) {
+        // Use functional rather than timing accesses during warmup
+        getMemReqQueue()->dequeue(clockEdge());
+        memoryPort.sendFunctional(pkt);
+        // Since the queue was popped the controller may be able
+        // to make more progress. Make sure it wakes up
+        scheduleEvent(Cycles(1));
+        recvTimingResp(pkt);
+    } else {
+        getMemReqQueue()->dequeue(clockEdge());
+        memoryPort.sendTimingReq(pkt);
+        // Since the queue was popped the controller may be able
+        // to make more progress. Make sure it wakes up
+        scheduleEvent(Cycles(1));
+    }
+
+    return true;
+}
+
 void
 AbstractController::blockOnQueue(Addr addr, MessageBuffer* port)
 {
@@ -237,76 +296,6 @@
 }

 void
-AbstractController::queueMemoryRead(const MachineID &id, Addr addr,
-                                    Cycles latency)
-{
-    RequestPtr req = new Request(addr, RubySystem::getBlockSizeBytes(), 0,
-                                 m_masterId);
-
-    PacketPtr pkt = Packet::createRead(req);
-    uint8_t *newData = new uint8_t[RubySystem::getBlockSizeBytes()];
-    pkt->dataDynamic(newData);
-
-    SenderState *s = new SenderState(id);
-    pkt->pushSenderState(s);
-
-    // Use functional rather than timing accesses during warmup
-    if (RubySystem::getWarmupEnabled()) {
-        memoryPort.sendFunctional(pkt);
-        recvTimingResp(pkt);
-        return;
-    }
-
-    memoryPort.schedTimingReq(pkt, clockEdge(latency));
-}
-
-void
-AbstractController::queueMemoryWrite(const MachineID &id, Addr addr,
- Cycles latency, const DataBlock &block)
-{
-    RequestPtr req = new Request(addr, RubySystem::getBlockSizeBytes(), 0,
-                                 m_masterId);
-
-    PacketPtr pkt = Packet::createWrite(req);
-    uint8_t *newData = new uint8_t[RubySystem::getBlockSizeBytes()];
-    pkt->dataDynamic(newData);
-    memcpy(newData, block.getData(0, RubySystem::getBlockSizeBytes()),
-           RubySystem::getBlockSizeBytes());
-
-    SenderState *s = new SenderState(id);
-    pkt->pushSenderState(s);
-
-    // Use functional rather than timing accesses during warmup
-    if (RubySystem::getWarmupEnabled()) {
-        memoryPort.sendFunctional(pkt);
-        recvTimingResp(pkt);
-        return;
-    }
-
-    // Create a block and copy data from the block.
-    memoryPort.schedTimingReq(pkt, clockEdge(latency));
-}
-
-void
-AbstractController::queueMemoryWritePartial(const MachineID &id, Addr addr,
-                                            Cycles latency,
- const DataBlock &block, int size)
-{
-    RequestPtr req = new Request(addr, size, 0, m_masterId);
-
-    PacketPtr pkt = Packet::createWrite(req);
-    uint8_t *newData = new uint8_t[size];
-    pkt->dataDynamic(newData);
-    memcpy(newData, block.getData(getOffset(addr), size), size);
-
-    SenderState *s = new SenderState(id);
-    pkt->pushSenderState(s);
-
-    // Create a block and copy data from the block.
-    memoryPort.schedTimingReq(pkt, clockEdge(latency));
-}
-
-void
 AbstractController::functionalMemoryRead(PacketPtr pkt)
 {
     memoryPort.sendFunctional(pkt);
@@ -330,7 +319,7 @@
 void
 AbstractController::recvTimingResp(PacketPtr pkt)
 {
-    assert(getMemoryQueue());
+    assert(getMemRespQueue());
     assert(pkt->isResponse());

std::shared_ptr<MemoryMsg> msg = std::make_shared<MemoryMsg>(clockEdge());
@@ -355,7 +344,7 @@
         panic("Incorrect packet type received from memory controller!");
     }

-    getMemoryQueue()->enqueue(msg, clockEdge(), cyclesToTicks(Cycles(1)));
+    getMemRespQueue()->enqueue(msg, clockEdge(), cyclesToTicks(Cycles(1)));
     delete pkt->req;
     delete pkt;
 }
diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh
index 35cd3d2..0aa6789 100644
--- a/src/mem/ruby/slicc_interface/AbstractController.hh
+++ b/src/mem/ruby/slicc_interface/AbstractController.hh
@@ -90,7 +90,8 @@
     bool isBlocked(Addr);

     virtual MessageBuffer* getMandatoryQueue() const = 0;
-    virtual MessageBuffer* getMemoryQueue() const = 0;
+    virtual MessageBuffer* getMemReqQueue() const = 0;
+    virtual MessageBuffer* getMemRespQueue() const = 0;
     virtual AccessPermission getAccessPermission(const Addr &addr) = 0;

     virtual void print(std::ostream & out) const = 0;
@@ -129,11 +130,6 @@
     BaseMasterPort& getMasterPort(const std::string& if_name,
                                   PortID idx = InvalidPortID);

-    void queueMemoryRead(const MachineID &id, Addr addr, Cycles latency);
-    void queueMemoryWrite(const MachineID &id, Addr addr, Cycles latency,
-                          const DataBlock &block);
- void queueMemoryWritePartial(const MachineID &id, Addr addr, Cycles latency,
-                                 const DataBlock &block, int size);
     void recvTimingResp(PacketPtr pkt);
     Tick recvAtomic(PacketPtr pkt);

@@ -171,6 +167,7 @@
     void wakeUpBuffers(Addr addr);
     void wakeUpAllBuffers(Addr addr);
     void wakeUpAllBuffers();
+    bool serviceMemoryQueue(PacketPtr pkt);

   protected:
     const NodeID m_version;
diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py
index 3f4e43a..7eb0aef 100644
--- a/src/mem/slicc/symbols/StateMachine.py
+++ b/src/mem/slicc/symbols/StateMachine.py
@@ -299,7 +299,8 @@
     void init();

     MessageBuffer *getMandatoryQueue() const;
-    MessageBuffer *getMemoryQueue() const;
+    MessageBuffer *getMemReqQueue() const;
+    MessageBuffer *getMemRespQueue() const;
     void initNetQueues();

     void print(std::ostream& out) const;
@@ -672,6 +673,11 @@
             if port.code.find("mandatoryQueue_ptr") >= 0:
                 mq_ident = "m_mandatoryQueue_ptr"

+        memoutq_ident = "NULL"
+        for param in self.config_parameters:
+            if param.ident.find("requestToMemory") >= 0:
+                memoutq_ident = "m_requestToMemory_ptr"
+
         memq_ident = "NULL"
         for port in self.in_ports:
             if port.code.find("responseFromMemory_ptr") >= 0:
@@ -854,7 +860,13 @@
 }

 MessageBuffer*
-$c_ident::getMemoryQueue() const
+$c_ident::getMemReqQueue() const
+{
+    return $memoutq_ident;
+}
+
+MessageBuffer*
+$c_ident::getMemRespQueue() const
 {
     return $memq_ident;
 }
@@ -1085,6 +1097,10 @@
 void
 ${ident}_Controller::wakeup()
 {
+    if (getMemReqQueue() && getMemReqQueue()->isReady(clockEdge())) {
+        serviceMemoryQueue(nullptr);
+    }
+
     int counter = 0;
     while (true) {
         unsigned char rejected[${{len(msg_bufs)}}];

--
To view, visit https://gem5-review.googlesource.com/8301
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I655b157be29e71abf06c7a6a8c1ef9c738e1ca54
Gerrit-Change-Number: 8301
Gerrit-PatchSet: 1
Gerrit-Owner: Matthew Poremba <matthew.pore...@amd.com>
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to