cpu: Move O3's data port into the LSQ.
authorGabe Black <gabeblack@google.com>
Sat, 17 Aug 2019 08:15:39 +0000 (01:15 -0700)
committerGabe Black <gabeblack@google.com>
Wed, 28 Aug 2019 02:14:29 +0000 (02:14 +0000)
That's where it's used, and putting it there avoids having to pass
around the port using the top level getDataPort function.

Change-Id: I0dea25d0c5f4bb3f58a6574a8f2b2d242784caf2
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20238
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Gabe Black <gabeblack@google.com>

src/cpu/o3/cpu.cc
src/cpu/o3/cpu.hh
src/cpu/o3/iew_impl.hh
src/cpu/o3/lsq.hh
src/cpu/o3/lsq_impl.hh

index 920bef02cd00a5615790f21c5407a2ab3bd70787..c9e01a5c2d1751b33a74b161013e79796446631e 100644 (file)
@@ -110,32 +110,6 @@ FullO3CPU<Impl>::IcachePort::recvReqRetry()
     fetch->recvReqRetry();
 }
 
-template <class Impl>
-bool
-FullO3CPU<Impl>::DcachePort::recvTimingResp(PacketPtr pkt)
-{
-    return lsq->recvTimingResp(pkt);
-}
-
-template <class Impl>
-void
-FullO3CPU<Impl>::DcachePort::recvTimingSnoopReq(PacketPtr pkt)
-{
-    for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
-        if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
-            cpu->wakeup(tid);
-        }
-    }
-    lsq->recvTimingSnoopReq(pkt);
-}
-
-template <class Impl>
-void
-FullO3CPU<Impl>::DcachePort::recvReqRetry()
-{
-    lsq->recvReqRetry();
-}
-
 template <class Impl>
 FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
     : BaseO3CPU(params),
@@ -175,7 +149,6 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
       isa(numThreads, NULL),
 
       icachePort(&fetch, this),
-      dcachePort(&iew.ldstQueue, this),
 
       timeBuffer(params->backComSize, params->forwardComSize),
       fetchQueue(params->backComSize, params->forwardComSize),
index 68ad95b182be9ad593e3e16805c053f8ec134cde..778c55bacd4f4323ec15a73094f4320e0d8d66e3 100644 (file)
@@ -158,49 +158,6 @@ class FullO3CPU : public BaseO3CPU
         virtual void recvReqRetry();
     };
 
-    /**
-     * DcachePort class for the load/store queue.
-     */
-    class DcachePort : public MasterPort
-    {
-      protected:
-
-        /** Pointer to LSQ. */
-        LSQ<Impl> *lsq;
-        FullO3CPU<Impl> *cpu;
-
-      public:
-        /** Default constructor. */
-        DcachePort(LSQ<Impl> *_lsq, FullO3CPU<Impl>* _cpu)
-            : MasterPort(_cpu->name() + ".dcache_port", _cpu), lsq(_lsq),
-              cpu(_cpu)
-        { }
-
-      protected:
-
-        /** Timing version of receive.  Handles writing back and
-         * completing the load or store that has returned from
-         * memory. */
-        virtual bool recvTimingResp(PacketPtr pkt);
-        virtual void recvTimingSnoopReq(PacketPtr pkt);
-
-        virtual void recvFunctionalSnoop(PacketPtr pkt)
-        {
-            // @todo: Is there a need for potential invalidation here?
-        }
-
-        /** Handles doing a retry of the previous send. */
-        virtual void recvReqRetry();
-
-        /**
-         * As this CPU requires snooping to maintain the load store queue
-         * change the behaviour from the base CPU port.
-         *
-         * @return true since we have to snoop
-         */
-        virtual bool isSnooping() const { return true; }
-    };
-
     /** The tick event used for scheduling CPU ticks. */
     EventFunctionWrapper tickEvent;
 
@@ -675,9 +632,6 @@ class FullO3CPU : public BaseO3CPU
     /** Instruction port. Note that it has to appear after the fetch stage. */
     IcachePort icachePort;
 
-    /** Data port. Note that it has to appear after the iew stages */
-    DcachePort dcachePort;
-
   public:
     /** Enum to give each stage a specific index, so when calling
      *  activateStage() or deactivateStage(), they can specify which stage
@@ -812,7 +766,11 @@ class FullO3CPU : public BaseO3CPU
     MasterPort &getInstPort() override { return icachePort; }
 
     /** Get the dcache port (used to find block size for translations). */
-    MasterPort &getDataPort() override { return dcachePort; }
+    MasterPort &
+    getDataPort() override
+    {
+        return this->iew.ldstQueue.getDataPort();
+    }
 
     /** Stat for total number of times the CPU is descheduled. */
     Stats::Scalar timesIdled;
index 5872f90d22733c99b66feea79f92611ca69c5b1b..cbdcdfc263f3d5950070164f022954baf5aacf36 100644 (file)
@@ -317,7 +317,7 @@ DefaultIEW<Impl>::startupStage()
 
     // Initialize the checker's dcache port here
     if (cpu->checker) {
-        cpu->checker->setDcachePort(&cpu->getDataPort());
+        cpu->checker->setDcachePort(&ldstQueue.getDataPort());
     }
 
     cpu->activateStage(O3CPU::IEWIdx);
index 29c76f7b69c23ceec7cd039e9b6274969edd3ab6..cc14ae42319174957bdbb32d9df7797f4376d4f5 100644 (file)
@@ -57,6 +57,9 @@
 
 struct DerivO3CPUParams;
 
+template <class Impl>
+class FullO3CPU;
+
 template <class Impl>
 class LSQ
 
@@ -115,6 +118,49 @@ class LSQ
         void writebackDone() { _request->writebackDone(); }
     };
 
+    /**
+     * DcachePort class for the load/store queue.
+     */
+    class DcachePort : public MasterPort
+    {
+      protected:
+
+        /** Pointer to LSQ. */
+        LSQ<Impl> *lsq;
+        FullO3CPU<Impl> *cpu;
+
+      public:
+        /** Default constructor. */
+        DcachePort(LSQ<Impl> *_lsq, FullO3CPU<Impl>* _cpu)
+            : MasterPort(_cpu->name() + ".dcache_port", _cpu), lsq(_lsq),
+              cpu(_cpu)
+        { }
+
+      protected:
+
+        /** Timing version of receive.  Handles writing back and
+         * completing the load or store that has returned from
+         * memory. */
+        virtual bool recvTimingResp(PacketPtr pkt);
+        virtual void recvTimingSnoopReq(PacketPtr pkt);
+
+        virtual void recvFunctionalSnoop(PacketPtr pkt)
+        {
+            // @todo: Is there a need for potential invalidation here?
+        }
+
+        /** Handles doing a retry of the previous send. */
+        virtual void recvReqRetry();
+
+        /**
+         * As this CPU requires snooping to maintain the load store queue
+         * change the behaviour from the base CPU port.
+         *
+         * @return true since we have to snoop
+         */
+        virtual bool isSnooping() const { return true; }
+    };
+
     /** Memory operation metadata.
      * This class holds the information about a memory operation. It lives
      * from initiateAcc to resource deallocation at commit or squash.
@@ -1004,6 +1050,8 @@ class LSQ
     /** Another store port is in use */
     void cachePortBusy(bool is_load);
 
+    MasterPort &getDataPort() { return dcachePort; }
+
   protected:
     /** D-cache is blocked */
     bool _cacheBlocked;
@@ -1057,6 +1105,9 @@ class LSQ
     /** Max SQ Size - Used to Enforce Sharing Policies. */
     unsigned maxSQEntries;
 
+    /** Data port. */
+    DcachePort dcachePort;
+
     /** The LSQ units for individual threads. */
     std::vector<LSQUnit> thread;
 
index a028424b0229f2897c7605c19ae0710e56114f5f..e885e61728cfe8de074d925890e666bec769b33a 100644 (file)
@@ -49,6 +49,7 @@
 #include <string>
 
 #include "base/logging.hh"
+#include "cpu/o3/cpu.hh"
 #include "cpu/o3/lsq.hh"
 #include "debug/Drain.hh"
 #include "debug/Fetch.hh"
@@ -71,6 +72,7 @@ LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
                   params->smtLSQThreshold)),
       maxSQEntries(maxLSQAllocation(lsqPolicy, SQEntries, params->numThreads,
                   params->smtLSQThreshold)),
+      dcachePort(this, cpu_ptr),
       numThreads(params->numThreads)
 {
     assert(numThreads > 0 && numThreads <= Impl::MaxThreads);
@@ -103,7 +105,7 @@ LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
     for (ThreadID tid = 0; tid < numThreads; tid++) {
         thread.emplace_back(maxLQEntries, maxSQEntries);
         thread[tid].init(cpu, iew_ptr, params, this, tid);
-        thread[tid].setDcachePort(&cpu_ptr->getDataPort());
+        thread[tid].setDcachePort(&dcachePort);
     }
 }
 
@@ -1164,4 +1166,30 @@ LSQ<Impl>::SplitDataRequest::isCacheBlockHit(Addr blockAddr, Addr blockMask)
     return is_hit;
 }
 
+template <class Impl>
+bool
+LSQ<Impl>::DcachePort::recvTimingResp(PacketPtr pkt)
+{
+    return lsq->recvTimingResp(pkt);
+}
+
+template <class Impl>
+void
+LSQ<Impl>::DcachePort::recvTimingSnoopReq(PacketPtr pkt)
+{
+    for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
+        if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
+            cpu->wakeup(tid);
+        }
+    }
+    lsq->recvTimingSnoopReq(pkt);
+}
+
+template <class Impl>
+void
+LSQ<Impl>::DcachePort::recvReqRetry()
+{
+    lsq->recvReqRetry();
+}
+
 #endif//__CPU_O3_LSQ_IMPL_HH__