changeset 0bf388858d1e in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=0bf388858d1e
description:
        ruby: Allow multiple outstanding DMA requests
        DMA sequencers and protocols can currently only issue one DMA access at
        a time. This patch implements the necessary functionality to support
        multiple outstanding DMA requests in Ruby.

diffstat:

 src/mem/protocol/MESI_Two_Level-dma.sm      |  84 ++++++++++++++++++++++++----
 src/mem/protocol/MI_example-dma.sm          |  86 +++++++++++++++++++++++-----
 src/mem/protocol/MOESI_CMP_directory-dma.sm |   4 +-
 src/mem/protocol/MOESI_CMP_token-dma.sm     |  84 +++++++++++++++++++++++-----
 src/mem/protocol/MOESI_hammer-dma.sm        |  86 +++++++++++++++++++++++-----
 src/mem/protocol/RubySlicc_Types.sm         |   4 +-
 src/mem/ruby/system/DMASequencer.cc         |  84 +++++++++++++++++++---------
 src/mem/ruby/system/DMASequencer.hh         |  23 +++++--
 src/mem/ruby/system/Sequencer.py            |   1 +
 9 files changed, 360 insertions(+), 96 deletions(-)

diffs (truncated from 859 to 300 lines):

diff -r 5e7599457b97 -r 0bf388858d1e src/mem/protocol/MESI_Two_Level-dma.sm
--- a/src/mem/protocol/MESI_Two_Level-dma.sm    Wed Oct 26 22:48:33 2016 -0400
+++ b/src/mem/protocol/MESI_Two_Level-dma.sm    Wed Oct 26 22:48:37 2016 -0400
@@ -50,15 +50,38 @@
     Ack,          desc="DMA write to memory completed";
   }
 
-  State cur_state;
+  structure(TBE, desc="...") {
+    State TBEState,    desc="Transient state";
+    DataBlock DataBlk, desc="Data";
+  }
+
+  structure(TBETable, external = "yes") {
+    TBE lookup(Addr);
+    void allocate(Addr);
+    void deallocate(Addr);
+    bool isPresent(Addr);
+  }
+
+  void set_tbe(TBE b);
+  void unset_tbe();
+  void wakeUpAllBuffers();
+
+  TBETable TBEs, template="<DMA_TBE>", constructor="m_number_of_TBEs";
+
   Tick clockEdge();
 
-  State getState(Addr addr) {
-    return cur_state;
+  State getState(TBE tbe, Addr addr) {
+    if (is_valid(tbe)) {
+        return tbe.TBEState;
+    } else {
+        return State:READY;
+    }
   }
 
-  void setState(Addr addr, State state) {
-    cur_state := state;
+  void setState(TBE tbe, Addr addr, State state) {
+    if (is_valid(tbe)) {
+        tbe.TBEState := state;
+    }
   }
 
   AccessPermission getAccessPermission(Addr addr) {
@@ -82,9 +105,9 @@
     if (dmaRequestQueue_in.isReady(clockEdge())) {
       peek(dmaRequestQueue_in, SequencerMsg) {
         if (in_msg.Type == SequencerRequestType:LD ) {
-          trigger(Event:ReadRequest, in_msg.LineAddress);
+          trigger(Event:ReadRequest, in_msg.LineAddress, 
TBEs[in_msg.LineAddress]);
         } else if (in_msg.Type == SequencerRequestType:ST) {
-          trigger(Event:WriteRequest, in_msg.LineAddress);
+          trigger(Event:WriteRequest, in_msg.LineAddress, 
TBEs[in_msg.LineAddress]);
         } else {
           error("Invalid request type");
         }
@@ -96,9 +119,11 @@
     if (dmaResponseQueue_in.isReady(clockEdge())) {
       peek( dmaResponseQueue_in, ResponseMsg) {
         if (in_msg.Type == CoherenceResponseType:ACK) {
-          trigger(Event:Ack, makeLineAddress(in_msg.addr));
+          trigger(Event:Ack, makeLineAddress(in_msg.addr),
+                  TBEs[makeLineAddress(in_msg.addr)]);
         } else if (in_msg.Type == CoherenceResponseType:DATA) {
-          trigger(Event:Data, makeLineAddress(in_msg.addr));
+          trigger(Event:Data, makeLineAddress(in_msg.addr),
+                  TBEs[makeLineAddress(in_msg.addr)]);
         } else {
           error("Invalid response type");
         }
@@ -133,15 +158,30 @@
   }
 
   action(a_ackCallback, "a", desc="Notify dma controller that write request 
completed") {
-    dma_sequencer.ackCallback();
+    dma_sequencer.ackCallback(address);
   }
 
   action(d_dataCallback, "d", desc="Write data to dma sequencer") {
-    peek (dmaResponseQueue_in, ResponseMsg) {
-      dma_sequencer.dataCallback(in_msg.DataBlk);
+    dma_sequencer.dataCallback(tbe.DataBlk, address);
+  }
+
+  action(t_updateTBEData, "t", desc="Update TBE Data") {
+    assert(is_valid(tbe));
+    peek( dmaResponseQueue_in, ResponseMsg) {
+        tbe.DataBlk := in_msg.DataBlk;
     }
   }
 
+  action(v_allocateTBE, "v", desc="Allocate TBE entry") {
+    TBEs.allocate(address);
+    set_tbe(TBEs[address]);
+  }
+
+  action(w_deallocateTBE, "w", desc="Deallocate TBE entry") {
+    TBEs.deallocate(address);
+    unset_tbe();
+  }
+
   action(p_popRequestQueue, "p", desc="Pop request queue") {
     dmaRequestQueue_in.dequeue(clockEdge());
   }
@@ -150,23 +190,43 @@
     dmaResponseQueue_in.dequeue(clockEdge());
   }
 
+  action(zz_stallAndWaitRequestQueue, "zz", desc="...") {
+    stall_and_wait(dmaRequestQueue_in, address);
+  }
+
+  action(wkad_wakeUpAllDependents, "wkad", desc="wake-up all dependents") {
+    wakeUpAllBuffers();
+  }
+
   transition(READY, ReadRequest, BUSY_RD) {
+    v_allocateTBE;
     s_sendReadRequest;
     p_popRequestQueue;
   }
 
   transition(READY, WriteRequest, BUSY_WR) {
+    v_allocateTBE;
     s_sendWriteRequest;
     p_popRequestQueue;
   }
 
   transition(BUSY_RD, Data, READY) {
+    t_updateTBEData;
     d_dataCallback;
+    w_deallocateTBE;
     p_popResponseQueue;
+    wkad_wakeUpAllDependents;
   }
 
   transition(BUSY_WR, Ack, READY) {
     a_ackCallback;
+    w_deallocateTBE;
     p_popResponseQueue;
+    wkad_wakeUpAllDependents;
   }
+
+  transition({BUSY_RD,BUSY_WR}, {ReadRequest,WriteRequest}) {
+     zz_stallAndWaitRequestQueue;
+  }
+
 }
diff -r 5e7599457b97 -r 0bf388858d1e src/mem/protocol/MI_example-dma.sm
--- a/src/mem/protocol/MI_example-dma.sm        Wed Oct 26 22:48:33 2016 -0400
+++ b/src/mem/protocol/MI_example-dma.sm        Wed Oct 26 22:48:37 2016 -0400
@@ -50,17 +50,38 @@
     Ack,          desc="DMA write to memory completed";
   }
 
-  State cur_state;
+  structure(TBE, desc="...") {
+    State TBEState,    desc="Transient state";
+    DataBlock DataBlk, desc="Data";
+  }
+
+  structure(TBETable, external = "yes") {
+    TBE lookup(Addr);
+    void allocate(Addr);
+    void deallocate(Addr);
+    bool isPresent(Addr);
+  }
+
+  void set_tbe(TBE b);
+  void unset_tbe();
+  void wakeUpAllBuffers();
+
+  TBETable TBEs, template="<DMA_TBE>", constructor="m_number_of_TBEs";
 
   Tick clockEdge();
-  Cycles ticksToCycles(Tick t);
 
-  State getState(Addr addr) {
-    return cur_state;
+  State getState(TBE tbe, Addr addr) {
+    if (is_valid(tbe)) {
+        return tbe.TBEState;
+    } else {
+        return State:READY;
+    }
   }
 
-  void setState(Addr addr, State state) {
-    cur_state := state;
+  void setState(TBE tbe, Addr addr, State state) {
+    if (is_valid(tbe)) {
+        tbe.TBEState := state;
+    }
   }
 
   AccessPermission getAccessPermission(Addr addr) {
@@ -84,9 +105,9 @@
     if (dmaRequestQueue_in.isReady(clockEdge())) {
       peek(dmaRequestQueue_in, SequencerMsg) {
         if (in_msg.Type == SequencerRequestType:LD ) {
-          trigger(Event:ReadRequest, in_msg.LineAddress);
+          trigger(Event:ReadRequest, in_msg.LineAddress, 
TBEs[in_msg.LineAddress]);
         } else if (in_msg.Type == SequencerRequestType:ST) {
-          trigger(Event:WriteRequest, in_msg.LineAddress);
+          trigger(Event:WriteRequest, in_msg.LineAddress, 
TBEs[in_msg.LineAddress]);
         } else {
           error("Invalid request type");
         }
@@ -98,9 +119,9 @@
     if (dmaResponseQueue_in.isReady(clockEdge())) {
       peek( dmaResponseQueue_in, DMAResponseMsg) {
         if (in_msg.Type == DMAResponseType:ACK) {
-          trigger(Event:Ack, in_msg.LineAddress);
+          trigger(Event:Ack, in_msg.LineAddress, TBEs[in_msg.LineAddress]);
         } else if (in_msg.Type == DMAResponseType:DATA) {
-          trigger(Event:Data, in_msg.LineAddress);
+          trigger(Event:Data, in_msg.LineAddress, TBEs[in_msg.LineAddress]);
         } else {
           error("Invalid response type");
         }
@@ -139,15 +160,28 @@
   }
 
   action(a_ackCallback, "a", desc="Notify dma controller that write request 
completed") {
-    peek (dmaResponseQueue_in, DMAResponseMsg) {
-      dma_sequencer.ackCallback();
+    dma_sequencer.ackCallback(address);
+  }
+
+  action(d_dataCallback, "d", desc="Write data to dma sequencer") {
+    dma_sequencer.dataCallback(tbe.DataBlk, address);
+  }
+
+  action(t_updateTBEData, "t", desc="Update TBE Data") {
+    assert(is_valid(tbe));
+    peek( dmaResponseQueue_in, DMAResponseMsg) {
+        tbe.DataBlk := in_msg.DataBlk;
     }
   }
 
-  action(d_dataCallback, "d", desc="Write data to dma sequencer") {
-    peek (dmaResponseQueue_in, DMAResponseMsg) {
-      dma_sequencer.dataCallback(in_msg.DataBlk);
-    }
+  action(v_allocateTBE, "v", desc="Allocate TBE entry") {
+    TBEs.allocate(address);
+    set_tbe(TBEs[address]);
+  }
+
+  action(w_deallocateTBE, "w", desc="Deallocate TBE entry") {
+    TBEs.deallocate(address);
+    unset_tbe();
   }
 
   action(p_popRequestQueue, "p", desc="Pop request queue") {
@@ -158,23 +192,43 @@
     dmaResponseQueue_in.dequeue(clockEdge());
   }
 
+  action(zz_stallAndWaitRequestQueue, "zz", desc="...") {
+    stall_and_wait(dmaRequestQueue_in, address);
+  }
+
+  action(wkad_wakeUpAllDependents, "wkad", desc="wake-up all dependents") {
+    wakeUpAllBuffers();
+  }
+
   transition(READY, ReadRequest, BUSY_RD) {
+    v_allocateTBE;
     s_sendReadRequest;
     p_popRequestQueue;
   }
 
   transition(READY, WriteRequest, BUSY_WR) {
+    v_allocateTBE;
     s_sendWriteRequest;
     p_popRequestQueue;
   }
 
   transition(BUSY_RD, Data, READY) {
+    t_updateTBEData;
     d_dataCallback;
+    w_deallocateTBE;
     p_popResponseQueue;
+    wkad_wakeUpAllDependents;
   }
 
   transition(BUSY_WR, Ack, READY) {
     a_ackCallback;
+    w_deallocateTBE;
     p_popResponseQueue;
+    wkad_wakeUpAllDependents;
   }
+
+  transition({BUSY_RD,BUSY_WR}, {ReadRequest,WriteRequest}) {
+     zz_stallAndWaitRequestQueue;
+  }
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to