MEM: Enable multiple distributed generalized memories
[gem5.git] / src / cpu / inorder / resource.hh
index 605b7f690e994b3234f256066c8ff0484b3687fe..3c1a8cc470e802d2995af82e18e4c559a268056b 100644 (file)
 #ifndef __CPU_INORDER_RESOURCE_HH__
 #define __CPU_INORDER_RESOURCE_HH__
 
-#include <vector>
 #include <list>
 #include <string>
+#include <vector>
 
 #include "base/types.hh"
-#include "cpu/inst_seq.hh"
 #include "cpu/inorder/inorder_dyn_inst.hh"
 #include "cpu/inorder/pipeline_traits.hh"
+#include "cpu/inst_seq.hh"
 #include "sim/eventq.hh"
 #include "sim/sim_object.hh"
 
@@ -51,6 +51,9 @@ class ResourceRequest;
 typedef ResourceRequest ResReq;
 typedef ResourceRequest* ResReqPtr;
 
+class CacheRequest;
+typedef CacheRequest* CacheReqPtr;
+
 class Resource {
   public:
     typedef ThePipeline::DynInstPtr DynInstPtr;
@@ -67,11 +70,6 @@ class Resource {
     /** Return name of this resource */
     virtual std::string name();
 
-    /** Define this function if resource, has a port to connect to an outside
-     *  simulation object.
-     */
-    virtual Port* getPort(const std::string &if_name, int idx) { return NULL; }
-
     /** Return ID for this resource */
     int getId() { return id; }
 
@@ -82,7 +80,7 @@ class Resource {
     virtual void initSlots();
 
     /** Register Stats for this resource */
-    virtual void regStats();
+    virtual void regStats() { }
 
     /** Resources that care about thread activation override this. */
     virtual void activateThread(ThreadID tid) { }
@@ -92,11 +90,22 @@ class Resource {
      */
     virtual void deactivateThread(ThreadID tid);
 
+    /** Resources that care about thread activation override this. */
+    virtual void suspendThread(ThreadID tid) { }
+    
+    /** Will be called the cycle before a context switch. Any bookkeeping
+     *  that needs to be kept for that, can be done here
+     */
+    virtual void updateAfterContextSwitch(DynInstPtr inst, ThreadID tid) { }    
+
     /** Resources that care when an instruction has been graduated
      *  can override this
      */
     virtual void instGraduated(InstSeqNum seq_num, ThreadID tid) { }
 
+    /** Post-processsing for Trap Generated from this instruction */
+    virtual void trap(Fault fault, ThreadID tid, DynInstPtr inst) { }
+
     /** Request usage of this resource. Returns a ResourceRequest object
      *  with all the necessary resource information
      */
@@ -114,16 +123,16 @@ class Resource {
     /** Free a resource slot */
     virtual void freeSlot(int slot_idx);
 
-    /** Request usage of a resource for this instruction. If this instruction already
-     *  has made this request to this resource, and that request is uncompleted
-     *  this function will just return that request
+    /** Request usage of a resource for this instruction. If this instruction 
+     *  already has made this request to this resource, and that request is 
+     *  uncompleted this function will just return that request
      */
     virtual ResourceRequest* getRequest(DynInstPtr _inst, int stage_num,
                                         int res_idx, int slot_num,
                                         unsigned cmd);
 
     /** Schedule Execution of This Resource For A Given Slot*/
-    virtual void scheduleExecution(int slot_idx);
+    void scheduleExecution(int slot_idx);
 
     /** Execute the function of this resource. The Default is action
      *  is to do nothing. More specific models will derive from this
@@ -142,19 +151,24 @@ class Resource {
      *  if instruction is actually in resource before
      *  trying to do access.Needs to be defined for derived units.
      */
-    virtual Fault doCacheAccess(DynInstPtr inst, uint64_t *res=NULL)
-    { panic("doCacheAccess undefined for %s", name()); return NoFault; }
+    virtual void doCacheAccess(DynInstPtr inst, uint64_t *write_result = NULL,
+                               CacheReqPtr split_req = NULL)
+    { panic("doCacheAccess undefined for %s", name()); }
 
-    virtual void prefetch(DynInstPtr inst)
-    { panic("prefetch undefined for %s", name()); }
-
-    virtual void writeHint(DynInstPtr inst)
-    { panic("writeHint undefined for %s", name()); }
+    /** Setup Squash to be sent out to pipeline and resource pool */
+    void setupSquash(DynInstPtr inst, int stage_num, ThreadID tid);
 
     /** Squash All Requests After This Seq Num */
     virtual void squash(DynInstPtr inst, int stage_num,
                         InstSeqNum squash_seq_num, ThreadID tid);
 
+    /** Squash Requests Due to a Memory Stall (By Default, same as "squash" */
+    virtual void squashDueToMemStall(DynInstPtr inst, int stage_num,
+                                     InstSeqNum squash_seq_num, ThreadID tid);
+
+    /** Handle Squash & Trap that occured from an instruction in a resource */
+    void squashThenTrap(int stage_num, DynInstPtr inst);
+
     /** The number of instructions available that this resource can
      *  can still process
      */
@@ -166,7 +180,8 @@ class Resource {
     /** Schedule resource event, regardless of its current state. */
     void scheduleEvent(int slot_idx, int delay);
 
-    /** Find instruction in list, Schedule resource event, regardless of its current state. */
+    /** Find instruction in list, Schedule resource event, regardless of its 
+     *  current state. */
     bool scheduleEvent(DynInstPtr inst, int delay);
 
     /** Unschedule resource event, regardless of its current state. */
@@ -182,7 +197,7 @@ class Resource {
     virtual ResReqPtr findRequest(DynInstPtr inst);
 
     /** */
-    virtual void rejectRequest(DynInstPtr inst);
+    void rejectRequest(DynInstPtr inst);
 
     /** Request a Resource again. Some resources have to special process this
      *  in subsequent accesses.
@@ -214,8 +229,10 @@ class Resource {
     const int latency;
 
   public:
-    /** Mapping of slot-numbers to the resource-request pointers */
-    std::map<int, ResReqPtr> reqMap;
+    /** List of all Requests the Resource is Servicing. Each request
+        represents part of the resource's bandwidth
+    */
+    std::vector<ResReqPtr> reqs;
 
     /** A list of all the available execution slots for this resource.
      *  This correlates with the actual resource event idx.
@@ -233,21 +250,12 @@ class Resource {
 
     /** Default denied resource request pointer*/
     ResReqPtr deniedReq;
-
-  public:
-    /////////////////////////////////////////////////////////////////
-    //
-    // DEFAULT RESOURCE STATISTICS
-    //
-    /////////////////////////////////////////////////////////////////
-    /** Number of Instruction Requests the Resource Processes */
-    Stats::Scalar instReqsProcessed;
 };
 
 class ResourceEvent : public Event
 {
   public:
-    /** Pointer to the CPU. */
+    /** Pointer to the Resource this is an event for */
     Resource *resource;
 
 
@@ -255,7 +263,7 @@ class ResourceEvent : public Event
     /// (for InOrderCPU model).
     /// check src/sim/eventq.hh for more event priorities.
     enum InOrderPriority {
-        Resource_Event_Pri     =   45,
+        Resource_Event_Pri = 45
     };
 
     /** The Resource Slot that this event is servicing */
@@ -273,19 +281,13 @@ class ResourceEvent : public Event
     virtual void process();
 
     /** Returns the description of the resource event. */
-    const char *description();
+    const char *description() const;
 
     /** Set slot idx for event */
     void setSlot(int slot) { slotIdx = slot; }
 
     /** Schedule resource event, regardless of its current state. */
-    void scheduleEvent(int delay)
-    {
-        if (squashed())
-          mainEventQueue.reschedule(this, curTick + resource->ticks(delay));
-        else if (!scheduled())
-          mainEventQueue.schedule(this, curTick + resource->ticks(delay));
-    }
+    void scheduleEvent(int delay);
 
     /** Unschedule resource event, regardless of its current state. */
     void unscheduleEvent()
@@ -303,36 +305,30 @@ class ResourceRequest
 
     static int resReqID;
 
-    static int resReqCount;
+    static int maxReqCount;
+    
+    friend class Resource;
 
   public:
-    ResourceRequest(Resource *_res, DynInstPtr _inst, int stage_num,
-                    int res_idx, int slot_num, unsigned _cmd)
-        : res(_res), inst(_inst), cmd(_cmd),  stageNum(stage_num),
-          resIdx(res_idx), slotNum(slot_num), completed(false),
-          squashed(false), processing(false), waiting(false)
-    {
-        reqID = resReqID++;
-        resReqCount++;
-        DPRINTF(ResReqCount, "Res. Req %i created. resReqCount=%i.\n", reqID, resReqCount);
+    ResourceRequest(Resource *_res);
+    
+    virtual ~ResourceRequest();
 
-        if (resReqCount > 100) {
-            fatal("Too many undeleted resource requests. Memory leak?\n");
-        }
-    }
+    std::string name();
+    
+    int reqID;
 
-    virtual ~ResourceRequest()
-    {
-        resReqCount--;
-        DPRINTF(ResReqCount, "Res. Req %i deleted. resReqCount=%i.\n", reqID, resReqCount);
-    }
+    void setRequest(DynInstPtr _inst, int stage_num,
+                    int res_idx, int slot_num, unsigned _cmd);
 
-    int reqID;
+    virtual void clearRequest();
 
     /** Acknowledge that this is a request is done and remove
      *  from resource.
      */
     void done(bool completed = true);
+    
+    void freeSlot();
 
     /////////////////////////////////////////////
     //
@@ -341,9 +337,10 @@ class ResourceRequest
     /////////////////////////////////////////////
     /** Get Resource Index */
     int getResIdx() { return resIdx; }
-
+       
     /** Get Slot Number */
     int getSlot() { return slotNum; }
+    bool hasSlot()  { return slotNum >= 0; }     
 
     /** Get Stage Number */
     int getStageNum() { return stageNum; }
@@ -366,12 +363,18 @@ class ResourceRequest
     /** Instruction being used */
     DynInstPtr inst;
 
-    /** Fault Associated With This Resource Request */
-    Fault fault;
-
+    /** Not guaranteed to be set, used for debugging */
+    InstSeqNum seqNum;
+    
     /** Command For This Resource */
     unsigned cmd;
 
+    short stagePasses;
+
+    bool valid;
+
+    bool doneInResource;
+
     ////////////////////////////////////////
     //
     // GET RESOURCE REQUEST STATUS FROM VARIABLES
@@ -387,11 +390,11 @@ class ResourceRequest
 
     /** Get/Set IsProcessing variables */
     bool isProcessing() { return processing; }
-    void setProcessing() { processing = true; }
+    void setProcessing(bool cond = true) { processing = cond; }
 
     /** Get/Set IsWaiting variables */
-    bool isWaiting() { return waiting; }
-    void setWaiting() { waiting = true; }
+    bool isMemStall() { return memStall; }
+    void setMemStall(bool stall = true) { memStall = stall; }
 
   protected:
     /** Resource Identification */
@@ -399,12 +402,13 @@ class ResourceRequest
     int stageNum;
     int resIdx;
     int slotNum;
-
-    /** Resource Status */
+    
+    /** Resource Request Status */
     bool completed;
     bool squashed;
     bool processing;
-    bool waiting;
+
+    bool memStall;
 };
 
 #endif //__CPU_INORDER_RESOURCE_HH__