mem-cache: Create an address aware TempCacheBlk
[gem5.git] / src / mem / simple_mem.hh
index 4f7af864b8fd21a6fa61b37148505dae22b42771..307981b80f0fbb6c246db1731d38e2b432285b21 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012-2013 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
  * SimpleMemory declaration
  */
 
-#ifndef __SIMPLE_MEMORY_HH__
-#define __SIMPLE_MEMORY_HH__
+#ifndef __MEM_SIMPLE_MEMORY_HH__
+#define __MEM_SIMPLE_MEMORY_HH__
+
+#include <list>
 
 #include "mem/abstract_mem.hh"
-#include "mem/tport.hh"
+#include "mem/port.hh"
 #include "params/SimpleMemory.hh"
 
 /**
  * The simple memory is a basic single-ported memory controller with
- * an configurable throughput and latency, potentially with a variance
- * added to the latter. It uses a QueueSlavePort to avoid dealing with
- * the flow control of sending responses.
+ * a configurable throughput and latency.
+ *
+ * @sa  \ref gem5MemorySystem "gem5 Memory System"
  */
 class SimpleMemory : public AbstractMemory
 {
 
   private:
 
-    class MemoryPort : public QueuedSlavePort
+    /**
+     * A deferred packet stores a packet along with its scheduled
+     * transmission time
+     */
+    class DeferredPacket
+    {
+
+      public:
+
+        const Tick tick;
+        const PacketPtr pkt;
+
+        DeferredPacket(PacketPtr _pkt, Tick _tick) : tick(_tick), pkt(_pkt)
+        { }
+    };
+
+    class MemoryPort : public SlavePort
     {
 
       private:
 
-        /// Queue holding the response packets
-        SlavePacketQueue queueImpl;
         SimpleMemory& memory;
 
       public:
@@ -85,16 +101,37 @@ class SimpleMemory : public AbstractMemory
 
         bool recvTimingReq(PacketPtr pkt);
 
+        void recvRespRetry();
+
         AddrRangeList getAddrRanges() const;
 
     };
 
     MemoryPort port;
 
-    Tick lat;
-    Tick lat_var;
+    /**
+     * Latency from that a request is accepted until the response is
+     * ready to be sent.
+     */
+    const Tick latency;
+
+    /**
+     * Fudge factor added to the latency.
+     */
+    const Tick latency_var;
+
+    /**
+     * Internal (unbounded) storage to mimic the delay caused by the
+     * actual memory access. Note that this is where the packet spends
+     * the memory latency.
+     */
+    std::list<DeferredPacket> packetQueue;
 
-    /// Bandwidth in ticks per byte
+    /**
+     * Bandwidth in ticks per byte. The regulation affects the
+     * acceptance rate of requests and the queueing takes place after
+     * the regulation.
+     */
     const double bandwidth;
 
     /**
@@ -109,31 +146,61 @@ class SimpleMemory : public AbstractMemory
      */
     bool retryReq;
 
+    /**
+     * Remember if we failed to send a response and are awaiting a
+     * retry. This is only used as a check.
+     */
+    bool retryResp;
+
     /**
      * Release the memory after being busy and send a retry if a
      * request was rejected in the meanwhile.
      */
     void release();
 
-    EventWrapper<SimpleMemory, &SimpleMemory::release> releaseEvent;
+    EventFunctionWrapper releaseEvent;
+
+    /**
+     * Dequeue a packet from our internal packet queue and move it to
+     * the port where it will be sent as soon as possible.
+     */
+    void dequeue();
+
+    EventFunctionWrapper dequeueEvent;
+
+    /**
+     * Detemine the latency.
+     *
+     * @return the latency seen by the current packet
+     */
+    Tick getLatency() const;
+
+    /**
+     * Upstream caches need this packet until true is returned, so
+     * hold it for deletion until a subsequent call
+     */
+    std::unique_ptr<Packet> pendingDelete;
 
   public:
 
     SimpleMemory(const SimpleMemoryParams *p);
-    virtual ~SimpleMemory() { }
 
-    unsigned int drain(Event* de);
+    DrainState drain() override;
 
-    virtual SlavePort& getSlavePort(const std::string& if_name, int idx = -1);
-    virtual void init();
+    BaseSlavePort& getSlavePort(const std::string& if_name,
+                                PortID idx = InvalidPortID) override;
+    void init() override;
 
   protected:
 
-    Tick doAtomicAccess(PacketPtr pkt);
-    void doFunctionalAccess(PacketPtr pkt);
+    Tick recvAtomic(PacketPtr pkt);
+
+    void recvFunctional(PacketPtr pkt);
+
     bool recvTimingReq(PacketPtr pkt);
-    Tick calculateLatency(PacketPtr pkt);
+
+    void recvRespRetry();
 
 };
 
-#endif //__SIMPLE_MEMORY_HH__
+#endif //__MEM_SIMPLE_MEMORY_HH__