cpu: Add TraceCPU to playback elastic traces
[gem5.git] / src / mem / protocol / MOESI_CMP_directory-dma.sm
index 30a311f6747dc6e7dde537842557eea35594d78a..72dec64662dec53215d0f10f1b9b44ea7a805f6a 100644 (file)
@@ -1,24 +1,54 @@
-
-machine(DMA, "DMA Controller") 
-: DMASequencer * dma_sequencer,
-  int request_latency = 14,
-  int response_latency = 14
+/*
+ * Copyright (c) 2009-2013 Mark D. Hill and David A. Wood
+ * Copyright (c) 2010-2011 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+machine(DMA, "DMA Controller")
+    : DMASequencer * dma_sequencer;
+      Cycles request_latency := 14;
+      Cycles response_latency := 14;
+
+      MessageBuffer * responseFromDir, network="From", virtual_network="2",
+            vnet_type="response";
+
+      MessageBuffer * reqToDir, network="To", virtual_network="1",
+            vnet_type="request";
+      MessageBuffer * respToDir, network="To", virtual_network="2",
+            vnet_type="dmaresponse";
+
+      MessageBuffer * mandatoryQueue;
+      MessageBuffer * triggerQueue;
 {
-  
-  MessageBuffer goo1, network="From", virtual_network="0", ordered="false";
-  MessageBuffer goo2, network="From", virtual_network="1", ordered="false";
-  MessageBuffer responseFromDir, network="From", virtual_network="2", ordered="false";
-
-  MessageBuffer foo1, network="To", virtual_network="0", ordered="false";
-  MessageBuffer reqToDir, network="To", virtual_network="1", ordered="false";
-  MessageBuffer respToDir, network="To", virtual_network="2", ordered="false";
-  
   state_declaration(State, desc="DMA states", default="DMA_State_READY") {
     READY, AccessPermission:Invalid, desc="Ready to accept a new request";
     BUSY_RD, AccessPermission:Busy, desc="Busy: currently processing a request";
     BUSY_WR, AccessPermission:Busy, desc="Busy: currently processing a request";
   }
-  
+
   enumeration(Event, desc="DMA events") {
     ReadRequest,  desc="A new read request";
     WriteRequest, desc="A new write request";
@@ -29,61 +59,53 @@ machine(DMA, "DMA Controller")
   }
 
   structure(TBE, desc="...") {
-    Address address, desc="Physical address";
+    Addr address, desc="Physical address";
     int NumAcks, default="0", desc="Number of Acks pending";
     DataBlock DataBlk, desc="Data";
   }
 
-  structure(DMASequencer, external = "yes") {
-    void ackCallback();
-    void dataCallback(DataBlock);
-  }
-
   structure(TBETable, external = "yes") {
-    TBE lookup(Address);
-    void allocate(Address);
-    void deallocate(Address);
-    bool isPresent(Address);
+    TBE lookup(Addr);
+    void allocate(Addr);
+    void deallocate(Addr);
+    bool isPresent(Addr);
   }
 
-  MessageBuffer mandatoryQueue, ordered="false";
-  MessageBuffer triggerQueue, ordered="true";
-  TBETable TBEs, template_hack="<DMA_TBE>";
+  TBETable TBEs, template="<DMA_TBE>", constructor="m_number_of_TBEs";
   State cur_state;
 
+  Tick clockEdge();
   void set_tbe(TBE b);
   void unset_tbe();
 
-  State getState(TBE tbe, Address addr) {
+  State getState(TBE tbe, Addr addr) {
     return cur_state;
   }
-  void setState(TBE tbe, Address addr, State state) {
+  void setState(TBE tbe, Addr addr, State state) {
   cur_state := state;
   }
 
-  out_port(reqToDirectory_out, RequestMsg, reqToDir, desc="...");
-  out_port(respToDirectory_out, ResponseMsg, respToDir, desc="...");
-  out_port(foo1_out, ResponseMsg, foo1, desc="...");
-  out_port(triggerQueue_out, TriggerMsg, triggerQueue, desc="...");
+  AccessPermission getAccessPermission(Addr addr) {
+    return AccessPermission:NotPresent;
+  }
 
-  in_port(goo1_in, RequestMsg, goo1) {
-    if (goo1_in.isReady()) {
-      peek(goo1_in, RequestMsg) {
-        assert(false);
-      }
-    }
+  void setAccessPermission(Addr addr, State state) {
   }
-  
-  in_port(goo2_in, RequestMsg, goo2) {
-    if (goo2_in.isReady()) {
-      peek(goo2_in, RequestMsg) {
-        assert(false);
-      }
-    }
+
+  void functionalRead(Addr addr, Packet *pkt) {
+    error("DMA does not support functional read.");
+  }
+
+  int functionalWrite(Addr addr, Packet *pkt) {
+    error("DMA does not support functional write.");
   }
 
+  out_port(reqToDirectory_out, RequestMsg, reqToDir, desc="...");
+  out_port(respToDirectory_out, ResponseMsg, respToDir, desc="...");
+  out_port(triggerQueue_out, TriggerMsg, triggerQueue, desc="...");
+
   in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") {
-    if (dmaRequestQueue_in.isReady()) {
+    if (dmaRequestQueue_in.isReady(clockEdge())) {
       peek(dmaRequestQueue_in, SequencerMsg) {
         if (in_msg.Type == SequencerRequestType:LD ) {
           trigger(Event:ReadRequest, in_msg.LineAddress,
@@ -99,18 +121,18 @@ machine(DMA, "DMA Controller")
   }
 
   in_port(dmaResponseQueue_in, ResponseMsg, responseFromDir, desc="...") {
-    if (dmaResponseQueue_in.isReady()) {
+    if (dmaResponseQueue_in.isReady(clockEdge())) {
       peek( dmaResponseQueue_in, ResponseMsg) {
         if (in_msg.Type == CoherenceResponseType:DMA_ACK) {
-          trigger(Event:DMA_Ack, makeLineAddress(in_msg.Address),
-                  TBEs[makeLineAddress(in_msg.Address)]);
+          trigger(Event:DMA_Ack, makeLineAddress(in_msg.addr),
+                  TBEs[makeLineAddress(in_msg.addr)]);
         } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE ||
        in_msg.Type == CoherenceResponseType:DATA) {
-          trigger(Event:Data, makeLineAddress(in_msg.Address),
-                  TBEs[makeLineAddress(in_msg.Address)]);
+          trigger(Event:Data, makeLineAddress(in_msg.addr),
+                  TBEs[makeLineAddress(in_msg.addr)]);
         } else if (in_msg.Type == CoherenceResponseType:ACK) {
-          trigger(Event:Inv_Ack, makeLineAddress(in_msg.Address),
-                  TBEs[makeLineAddress(in_msg.Address)]);
+          trigger(Event:Inv_Ack, makeLineAddress(in_msg.addr),
+                  TBEs[makeLineAddress(in_msg.addr)]);
         } else {
           error("Invalid response type");
         }
@@ -120,10 +142,10 @@ machine(DMA, "DMA Controller")
 
   // Trigger Queue
   in_port(triggerQueue_in, TriggerMsg, triggerQueue) {
-    if (triggerQueue_in.isReady()) {
+    if (triggerQueue_in.isReady(clockEdge())) {
       peek(triggerQueue_in, TriggerMsg) {
         if (in_msg.Type == TriggerType:ALL_ACKS) {
-          trigger(Event:All_Acks, in_msg.Address, TBEs[in_msg.Address]);
+          trigger(Event:All_Acks, in_msg.addr, TBEs[in_msg.addr]);
         } else {
           error("Unexpected message");
         }
@@ -133,13 +155,14 @@ machine(DMA, "DMA Controller")
 
   action(s_sendReadRequest, "s", desc="Send a DMA read request to memory") {
     peek(dmaRequestQueue_in, SequencerMsg) {
-      enqueue(reqToDirectory_out, RequestMsg, latency=request_latency) {
-        out_msg.Address := in_msg.PhysicalAddress;
+      enqueue(reqToDirectory_out, RequestMsg, request_latency) {
+        out_msg.addr := in_msg.PhysicalAddress;
         out_msg.Type := CoherenceRequestType:DMA_READ;
         out_msg.DataBlk := in_msg.DataBlk;
         out_msg.Len := in_msg.Len;
         out_msg.Destination.add(map_Address_to_Directory(address));
         out_msg.Requestor := machineID;
+        out_msg.RequestorMachine := MachineType:DMA;
         out_msg.MessageSize := MessageSizeType:Writeback_Control;
       }
     }
@@ -147,13 +170,14 @@ machine(DMA, "DMA Controller")
 
   action(s_sendWriteRequest, "\s", desc="Send a DMA write request to memory") {
     peek(dmaRequestQueue_in, SequencerMsg) {
-      enqueue(reqToDirectory_out, RequestMsg, latency=request_latency) {
-          out_msg.Address := in_msg.PhysicalAddress;
+      enqueue(reqToDirectory_out, RequestMsg, request_latency) {
+          out_msg.addr := in_msg.PhysicalAddress;
           out_msg.Type := CoherenceRequestType:DMA_WRITE;
           out_msg.DataBlk := in_msg.DataBlk;
           out_msg.Len := in_msg.Len;
           out_msg.Destination.add(map_Address_to_Directory(address));
           out_msg.Requestor := machineID;
+          out_msg.RequestorMachine := MachineType:DMA;
           out_msg.MessageSize := MessageSizeType:Writeback_Control;
         }
       }
@@ -167,7 +191,7 @@ machine(DMA, "DMA Controller")
     assert(is_valid(tbe));
     if (tbe.NumAcks == 0) {
       enqueue(triggerQueue_out, TriggerMsg) {
-        out_msg.Address := address;
+        out_msg.addr := address;
         out_msg.Type := TriggerType:ALL_ACKS;
       }
     }
@@ -181,24 +205,26 @@ machine(DMA, "DMA Controller")
   }
 
   action( u_sendExclusiveUnblockToDir, "\u", desc="send exclusive unblock to directory") {
-    enqueue(respToDirectory_out, ResponseMsg, latency=response_latency) {
-      out_msg.Address := address;
+    enqueue(respToDirectory_out, ResponseMsg, response_latency) {
+      out_msg.addr := address;
       out_msg.Type := CoherenceResponseType:UNBLOCK_EXCLUSIVE;
       out_msg.Destination.add(map_Address_to_Directory(address));
+      out_msg.Sender := machineID;
+      out_msg.SenderMachine := MachineType:DMA;
       out_msg.MessageSize := MessageSizeType:Writeback_Control;
     }
   }
 
   action(p_popRequestQueue, "p", desc="Pop request queue") {
-    dmaRequestQueue_in.dequeue();
+    dmaRequestQueue_in.dequeue(clockEdge());
   }
 
   action(p_popResponseQueue, "\p", desc="Pop request queue") {
-    dmaResponseQueue_in.dequeue();
+    dmaResponseQueue_in.dequeue(clockEdge());
   }
 
   action(p_popTriggerQueue, "pp", desc="Pop trigger queue") {
-    triggerQueue_in.dequeue();
+    triggerQueue_in.dequeue(clockEdge());
   }
 
   action(t_updateTBEData, "t", desc="Update TBE Data") {
@@ -223,11 +249,6 @@ machine(DMA, "DMA Controller")
     unset_tbe();
   }
 
-  action(z_stall, "z", desc="dma is busy..stall") {
-    // do nothing
-  }
-
-
 
   transition(READY, ReadRequest, BUSY_RD) {
     s_sendReadRequest;
@@ -276,7 +297,7 @@ machine(DMA, "DMA Controller")
   }
 
   transition(BUSY_WR, All_Acks, READY) {
-    a_ackCallback; 
+    a_ackCallback;
     u_sendExclusiveUnblockToDir;
     w_deallocateTBE;
     p_popTriggerQueue;