inorder-alpha-port: initial inorder support of ALPHA
authorKorey Sewell <ksewell@umich.edu>
Tue, 12 May 2009 19:01:13 +0000 (15:01 -0400)
committerKorey Sewell <ksewell@umich.edu>
Tue, 12 May 2009 19:01:13 +0000 (15:01 -0400)
Edit AlphaISA to support the inorder model. Mostly alternate constructor functions and also a few skeleton multithreaded support functions
* * *
Remove namespace from header file. Causes compiler issues that are hard to find
* * *
Separate the TLB from the CPU and allow it to live in the TLBUnit resource. Give CPU accessor functions for access and also bind at construction time
* * *
Expose memory access size and flags through instruction object
(temporarily memAccSize and memFlags to get TLB stuff working.)

16 files changed:
src/arch/SConscript
src/arch/alpha/floatregfile.hh
src/arch/alpha/isa/mem.isa
src/arch/alpha/miscregfile.cc
src/arch/alpha/miscregfile.hh
src/arch/mips/regfile/misc_regfile.hh
src/cpu/inorder/cpu.cc
src/cpu/inorder/cpu.hh
src/cpu/inorder/inorder_dyn_inst.hh
src/cpu/inorder/resource_pool.cc
src/cpu/inorder/resource_pool.hh
src/cpu/inorder/resources/cache_unit.cc
src/cpu/inorder/resources/mult_div_unit.cc
src/cpu/inorder/resources/tlb_unit.cc
src/cpu/inorder/resources/tlb_unit.hh
src/cpu/inorder/thread_context.hh

index b85ffbd89a91d8ceed2d5876ef116a10b998bdc1..0d801fcad7b1f03d28aa546828439ce9c956ad58 100644 (file)
@@ -51,6 +51,7 @@ isa_switch_hdrs = Split('''
         locked_mem.hh
         microcode_rom.hh
         mmaped_ipr.hh
+        mt.hh
         process.hh
         predecoder.hh
         regfile.hh
index d5f9eec0ff9f44a85df7338bc09559cbb3a264ef..a5a3a7861427fa9e82f7741ac0260d41664d8a2c 100644 (file)
@@ -42,6 +42,13 @@ class Checkpoint;
 
 namespace AlphaISA {
 
+const int SingleWidth = 32;
+const int SingleBytes = SingleWidth / 4;
+const int DoubleWidth = 64;
+const int DoubleBytes = DoubleWidth / 4;
+const int QuadWidth = 128;
+const int QuadBytes = QuadWidth / 4;
+
 class FloatRegFile
 {
   public:
@@ -54,6 +61,55 @@ class FloatRegFile
 
     void serialize(std::ostream &os);
     void unserialize(Checkpoint *cp, const std::string &section);
+
+    FloatReg
+    readReg(int floatReg)
+    {
+        return d[floatReg];
+    }
+
+    FloatReg
+    readReg(int floatReg, int width)
+    {
+        return readReg(floatReg);
+    }
+
+    FloatRegBits
+    readRegBits(int floatReg)
+    {
+        return q[floatReg];
+    }
+
+    FloatRegBits
+    readRegBits(int floatReg, int width)
+    {
+        return readRegBits(floatReg);
+    }
+
+    void
+    setReg(int floatReg, const FloatReg &val)
+    {
+        d[floatReg] = val;
+    }
+
+    void
+    setReg(int floatReg, const FloatReg &val, int width)
+    {
+        setReg(floatReg, val);
+    }
+
+    void
+    setRegBits(int floatReg, const FloatRegBits &val)
+    {
+        q[floatReg] = val;
+    }
+
+    void
+    setRegBits(int floatReg, const FloatRegBits &val, int width)
+    {
+        setRegBits(floatReg, val);
+    }
+
 };
 
 } // namespace AlphaISA
index cd5e117ec3f7bd2f11eaa6b8af8221f9f2e54aac..9a8503637da54d22915dcd4040353fa957cebe15 100644 (file)
@@ -65,6 +65,8 @@ output header {{
 
         const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
         const StaticInstPtr &memAccInst() const { return memAccPtr; }
+
+        Request::Flags memAccFlags() { return memAccessFlags; }
     };
 
     /**
@@ -176,6 +178,8 @@ def template LoadStoreDeclare {{
         %(InitiateAccDeclare)s
 
         %(CompleteAccDeclare)s
+
+        %(MemAccSizeDeclare)s
     };
 }};
 
@@ -190,6 +194,25 @@ def template CompleteAccDeclare {{
                       Trace::InstRecord *) const;
 }};
 
+def template MemAccSizeDeclare {{
+    int memAccSize(%(CPU_exec_context)s *xc);
+}};
+
+def template MiscMemAccSize {{
+    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
+    {
+        panic("Misc instruction does not support split access method!");
+        return 0;
+    }
+}};
+
+def template LoadStoreMemAccSize {{
+    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
+    {
+        // Return the memory access size in bytes
+        return (%(mem_acc_size)d / 8);
+    }
+}};
 
 def template EACompConstructor {{
     /** TODO: change op_class to AddrGenOp or something (requires
@@ -620,6 +643,14 @@ def template MiscCompleteAcc {{
     }
 }};
 
+def template MiscMemAccSize {{
+    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
+    {
+        panic("Misc instruction does not support split access method!");
+        return 0;
+    }
+}};
+
 // load instructions use Ra as dest, so check for
 // Ra == 31 to detect nops
 def template LoadNopCheckDecode {{
@@ -693,6 +724,11 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
     initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
     completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
 
+    if (exec_template_base == 'Load' or exec_template_base == 'Store'):
+      memAccSizeTemplate = eval('LoadStoreMemAccSize')
+    else:
+      memAccSizeTemplate = eval('MiscMemAccSize')
+
     # (header_output, decoder_output, decode_block, exec_output)
     return (LoadStoreDeclare.subst(iop),
             EACompConstructor.subst(ea_iop)
@@ -703,7 +739,8 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
             + memAccExecTemplate.subst(memacc_iop)
             + fullExecTemplate.subst(iop)
             + initiateAccTemplate.subst(iop)
-            + completeAccTemplate.subst(iop))
+            + completeAccTemplate.subst(iop)
+            + memAccSizeTemplate.subst(memacc_iop))
 }};
 
 def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
index 61a86f1fb7af261e66ef88200c4df5f7feaee670..5dc316a839ad7ef9cbee6dcac660cb3634d98e05 100644 (file)
@@ -57,8 +57,15 @@ MiscRegFile::unserialize(Checkpoint *cp, const std::string &section)
     UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs);
 }
 
+MiscRegFile::MiscRegFile(BaseCPU *_cpu)
+{
+    cpu = _cpu;
+    initializeIprTable();
+}
+
+
 MiscReg
-MiscRegFile::readRegNoEffect(int misc_reg)
+MiscRegFile::readRegNoEffect(int misc_reg, unsigned tid )
 {
     switch (misc_reg) {
       case MISCREG_FPCR:
@@ -78,7 +85,7 @@ MiscRegFile::readRegNoEffect(int misc_reg)
 }
 
 MiscReg
-MiscRegFile::readReg(int misc_reg, ThreadContext *tc)
+MiscRegFile::readReg(int misc_reg, ThreadContext *tc, unsigned tid )
 {
     switch (misc_reg) {
       case MISCREG_FPCR:
@@ -97,7 +104,7 @@ MiscRegFile::readReg(int misc_reg, ThreadContext *tc)
 }
 
 void
-MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val)
+MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid)
 {
     switch (misc_reg) {
       case MISCREG_FPCR:
@@ -123,7 +130,8 @@ MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val)
 }
 
 void
-MiscRegFile::setReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
+MiscRegFile::setReg(int misc_reg, const MiscReg &val, ThreadContext *tc,
+                    unsigned tid)
 {
     switch (misc_reg) {
       case MISCREG_FPCR:
index 6105ce6837b7d277d3494cda1d9b99fd6932e7c6..b194e00bb2a3d42a5d1e9a0c3aedd83bae0e1521 100644 (file)
@@ -41,6 +41,7 @@
 
 class Checkpoint;
 class ThreadContext;
+class BaseCPU;
 
 namespace AlphaISA {
 
@@ -68,6 +69,8 @@ class MiscRegFile
 
     InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
 
+    BaseCPU *cpu;
+
   protected:
     InternalProcReg readIpr(int idx, ThreadContext *tc);
     void setIpr(int idx, InternalProcReg val, ThreadContext *tc);
@@ -78,16 +81,18 @@ class MiscRegFile
         initializeIprTable();
     }
 
+    MiscRegFile(BaseCPU *cpu);
+
     // These functions should be removed once the simplescalar cpu
     // model has been replaced.
     int getInstAsid();
     int getDataAsid();
 
-    MiscReg readRegNoEffect(int misc_reg);
-    MiscReg readReg(int misc_reg, ThreadContext *tc);
+    MiscReg readRegNoEffect(int misc_reg, unsigned tid = 0);
+    MiscReg readReg(int misc_reg, ThreadContext *tc, unsigned tid = 0);
 
-    void setRegNoEffect(int misc_reg, const MiscReg &val);
-    void setReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
+    void setRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid = 0);
+    void setReg(int misc_reg, const MiscReg &val, ThreadContext *tc, unsigned tid = 0);
 
     void
     clear()
@@ -101,6 +106,16 @@ class MiscRegFile
 
     void serialize(std::ostream &os);
     void unserialize(Checkpoint *cp, const std::string &section);
+
+    void reset(std::string core_name, unsigned num_threads,
+               unsigned num_vpes, BaseCPU *_cpu)
+    { }
+
+
+    void expandForMultithreading(unsigned num_threads, unsigned num_vpes)
+    { }
+
+
 };
 
 void copyIprs(ThreadContext *src, ThreadContext *dest);
index c611d94cca29813f54772e9e2efa0d25117df8e6..0daf8f718b64bac17b0bddd592f5772547872ade 100644 (file)
@@ -69,7 +69,7 @@ namespace MipsISA
 
       public:
         MiscRegFile();
-        MiscRegFile(BaseCPU *cpu);
+        MiscRegFile(BaseCPU *_cpu);
 
         void init();
 
index 0b38f39bcf56649f13b10d678375f76e6bb27794..83e94e74dd9f99e5bf57fa1cc265169cc631e246 100644 (file)
@@ -180,15 +180,26 @@ InOrderCPU::InOrderCPU(Params *params)
     // Bind the fetch & data ports from the resource pool.
     fetchPortIdx = resPool->getPortIdx(params->fetchMemPort);
     if (fetchPortIdx == 0) {
-        warn("Unable to find port to fetch instructions from.\n");
+        fatal("Unable to find port to fetch instructions from.\n");
     }
 
     dataPortIdx = resPool->getPortIdx(params->dataMemPort);
     if (dataPortIdx == 0) {
-        warn("Unable to find port for data.\n");
+        fatal("Unable to find port for data.\n");
     }
 
 
+    // Hard-Code Bindings to ITB & DTB
+    itbIdx = resPool->getResIdx(name() + "."  + "I-TLB");
+    if (itbIdx == 0) {
+        fatal("Unable to find ITB resource.\n");
+    }
+
+    dtbIdx = resPool->getResIdx(name() + "."  + "D-TLB");
+    if (dtbIdx == 0) {
+        fatal("Unable to find DTB resource.\n");
+    }
+
     for (int i = 0; i < numThreads; ++i) {
         if (i < params->workload.size()) {
             DPRINTF(InOrderCPU, "Workload[%i] process is %#x\n",
@@ -814,6 +825,13 @@ InOrderCPU::removeThread(unsigned tid)
     /** Broadcast to CPU resources*/
 }
 
+PipelineStage*
+InOrderCPU::getPipeStage(int stage_num)
+{
+    return pipelineStage[stage_num];
+}
+
+
 void
 InOrderCPU::activateWhenReady(int tid)
 {
@@ -1245,3 +1263,18 @@ InOrderCPU::write(DynInstPtr inst)
     Resource *mem_res = resPool->getResource(dataPortIdx);
     return mem_res->doDataAccess(inst);
 }
+
+TheISA::ITB*
+InOrderCPU::getITBPtr()
+{
+    TLBUnit *itb_res = dynamic_cast<TLBUnit*>(resPool->getResource(itbIdx));
+    return dynamic_cast<TheISA::ITB*>(itb_res->tlb());
+}
+
+
+TheISA::DTB*
+InOrderCPU::getDTBPtr()
+{
+    TLBUnit *dtb_res = dynamic_cast<TLBUnit*>(resPool->getResource(dtbIdx));
+    return dynamic_cast<TheISA::DTB*>(dtb_res->tlb());
+}
index 744dd5cf900de08de4f249fb601cae149cc4876a..8b2442ac05de77ca2b3f408ee5bcd1c8f1f94bc2 100644 (file)
@@ -103,9 +103,6 @@ class InOrderCPU : public BaseCPU
 
     Params *cpu_params;
 
-    TheISA::TLB * itb;
-    TheISA::TLB * dtb;
-
   public:
     enum Status {
         Running,
@@ -236,11 +233,17 @@ class InOrderCPU : public BaseCPU
      */
     unsigned fetchPortIdx;
 
+    /** Identifies the resource id that identifies a ITB       */
+    unsigned itbIdx;
+
     /** Identifies the resource id that identifies a data
      * access unit.
      */
     unsigned dataPortIdx;
 
+    /** Identifies the resource id that identifies a DTB       */
+    unsigned dtbIdx;
+
     /** The Pipeline Stages for the CPU */
     PipelineStage *pipelineStage[ThePipeline::NumStages];
 
@@ -262,6 +265,9 @@ class InOrderCPU : public BaseCPU
     /** Communication structure that sits in between pipeline stages */
     StageQueue *stageQueue[ThePipeline::NumStages-1];
 
+    TheISA::ITB *getITBPtr();
+    TheISA::DTB *getDTBPtr();
+
   public:
 
     /** Registers statistics. */
@@ -308,6 +314,8 @@ class InOrderCPU : public BaseCPU
     void deallocateThread(unsigned tid);
     void deactivateThread(unsigned tid);
 
+    PipelineStage* getPipeStage(int stage_num);
+
     int
     contextId()
     {
index 3b47624fbb071f9540086a4fe6c2dc5b8af00035..12a9a41760c1ad62a46fc8df9d4f2beee651a91b 100644 (file)
 #include <list>
 #include <string>
 
+#include "arch/isa_traits.hh"
 #include "arch/faults.hh"
+#include "arch/types.hh"
+#include "arch/mt.hh"
 #include "base/fast_alloc.hh"
 #include "base/trace.hh"
 #include "cpu/inorder/inorder_trace.hh"
@@ -827,6 +830,10 @@ class InOrderDynInst : public FastAlloc, public RefCounted
     virtual uint64_t readRegOtherThread(unsigned idx, int tid = -1);
     virtual void setRegOtherThread(unsigned idx, const uint64_t &val, int tid = -1);
 
+    /** Sets the number of consecutive store conditional failures. */
+    void setStCondFailures(unsigned sc_failures)
+    { thread->storeCondFailures = sc_failures; }
+
     //////////////////////////////////////////////////////////////
     //
     // INSTRUCTION STATUS FLAGS (READ/SET)
index 94af68c7af7626bef271889c5614610372bfc033..725f6cbb3ccf56d601e2bee1b12af4ba04fdef25 100644 (file)
@@ -143,6 +143,21 @@ ResourcePool::getPortIdx(const std::string &port_name)
     return 0;
 }
 
+unsigned
+ResourcePool::getResIdx(const std::string &res_name)
+{
+    DPRINTF(Resource, "Finding Resource Idx for %s.\n", res_name);
+
+    int num_resources = resources.size();
+
+    for (int idx = 0; idx < num_resources; idx++) {
+        if (resources[idx]->name() == res_name)
+            return idx;
+    }
+
+    return 0;
+}
+
 ResReqPtr
 ResourcePool::request(int res_idx, DynInstPtr inst)
 {
index 35fce7db74f4d51c4e914d9d97063802879b49c5..6cc1f77e6a00e487d46ccc96eb1ba87563f94727 100644 (file)
@@ -131,8 +131,12 @@ class ResourcePool {
     Port* getPort(const std::string &if_name, int idx);
 
     /** Returns a specific port. */
-    unsigned getPortIdx(const std::string &if_name);
+    unsigned getPortIdx(const std::string &port_name);
 
+    /** Returns a specific resource. */
+    unsigned getResIdx(const std::string &res_name);
+
+    /** Returns a pointer to a resource */
     Resource* getResource(int res_idx) { return resources[res_idx]; }
 
     /** Request usage of this resource. Returns -1 if not granted and
index 772437638ef87da71f51f01207b51492accefd25..d273d72470d85486801369898e38756c43ddeb0a 100644 (file)
@@ -32,7 +32,7 @@
 #include <vector>
 #include <list>
 #include "arch/isa_traits.hh"
-#include "arch/mips/locked_mem.hh"
+#include "arch/locked_mem.hh"
 #include "arch/utility.hh"
 #include "cpu/inorder/resources/cache_unit.hh"
 #include "cpu/inorder/pipeline_traits.hh"
index b31d60ad51b2e9c9f48c6fd80b6e302a5387c0ad..df9d4c2932b8a231dc581a8f6bd79f821b5dda52 100644 (file)
@@ -47,7 +47,7 @@ MultDivUnit::MultDivUnit(string res_name, int res_id, int res_width,
       div16RepeatRate(params->div16RepeatRate), div16Latency(params->div16Latency), 
       div24RepeatRate(params->div24RepeatRate), div24Latency(params->div24Latency), 
       div32RepeatRate(params->div32RepeatRate), div32Latency(params->div32Latency), 
-      lastMDUCycle(0)
+      lastMDUCycle(0), lastOpType(No_OpClass)
 { }
 
 void
index b3757d707e76b273d918b21dec8600d48bedb076..fbc6bc195feb98e9c06f97fbe9c25728a34e5f3e 100644 (file)
@@ -33,6 +33,7 @@
 #include <list>
 #include "arch/isa_traits.hh"
 #include "cpu/inorder/pipeline_traits.hh"
+#include "cpu/inorder/first_stage.hh"
 #include "cpu/inorder/resources/tlb_unit.hh"
 #include "cpu/inorder/cpu.hh"
 
@@ -44,11 +45,26 @@ TLBUnit::TLBUnit(string res_name, int res_id, int res_width,
                  int res_latency, InOrderCPU *_cpu, ThePipeline::Params *params)
     : InstBuffer(res_name, res_id, res_width, res_latency, _cpu, params)
 {
+    // Hard-Code Selection For Now
+    if (res_name == "I-TLB")
+        _tlb = params->itb;
+    else if (res_name == "D-TLB")
+        _tlb = params->dtb;
+    else
+        fatal("Unrecognized TLB name passed by user");
+
     for (int i=0; i < MaxThreads; i++) {
         tlbBlocked[i] = false;
     }
 }
 
+TheISA::TLB*
+TLBUnit::tlb()
+{
+    return _tlb;
+
+}
+
 void
 TLBUnit::init()
 {
@@ -82,7 +98,7 @@ TLBUnit::execute(int slot_idx)
     // After this is working, change this to a reinterpret cast
     // for performance considerations
     TLBUnitRequest* tlb_req = dynamic_cast<TLBUnitRequest*>(reqMap[slot_idx]);
-    assert(tlb_req);
+    assert(tlb_req != 0x0);
 
     DynInstPtr inst = tlb_req->inst;
     int tid, seq_num, stage_num;
@@ -93,12 +109,15 @@ TLBUnit::execute(int slot_idx)
 
     tlb_req->fault = NoFault;
 
+    assert(cpu->thread[tid]->getTC() != 0x0);
+    assert(cpu->pipelineStage[stage_num] != 0x0);
+
     switch (tlb_req->cmd)
     {
       case FetchLookup:
         {
             tlb_req->fault =
-                this->cpu->itb->translateAtomic(tlb_req->memReq,
+                _tlb->translateAtomic(tlb_req->memReq,
                         cpu->thread[tid]->getTC(), false, true);
 
             if (tlb_req->fault != NoFault) {
@@ -129,7 +148,7 @@ TLBUnit::execute(int slot_idx)
                     tid, seq_num, tlb_req->memReq->getVaddr());
 
             tlb_req->fault =
-                this->cpu->itb->translateAtomic(tlb_req->memReq,
+                _tlb->translateAtomic(tlb_req->memReq,
                         cpu->thread[tid]->getTC());
 
             if (tlb_req->fault != NoFault) {
index c7fee6030829b1b20f4e4b2c38529182045ba10d..b53f251fc10b85e669d2571da1231672062c499b 100644 (file)
@@ -67,14 +67,15 @@ class TLBUnit : public InstBuffer {
 
     bool tlbBlocked[ThePipeline::MaxThreads];
 
+    TheISA::TLB* tlb();
+
   protected:
     /** List of instructions this resource is currently
      *  processing.
      */
     std::list<DynInstPtr> instList;
 
-    /** @todo: Add Resource Stats Here */
-
+    TheISA::TLB *_tlb;
 };
 
 class TLBUnitEvent : public ResourceEvent {
index ec8cc197996295b5ce1b2335e0c80fa1c6424161..cde377dfc88de5e787ac547a4dfddf00418670f7 100644 (file)
@@ -57,7 +57,7 @@ class InOrderThreadContext : public ThreadContext
   public:
     InOrderThreadContext() { }
 
-   /** Pointer to the CPU. */
+    /** Pointer to the CPU. */
     InOrderCPU *cpu;
 
     /** Pointer to the thread state that this TC corrseponds to. */
@@ -65,10 +65,12 @@ class InOrderThreadContext : public ThreadContext
 
 
     /** Returns a pointer to the ITB. */
-    TheISA::TLB *getITBPtr() { return cpu->itb; }
+    /** @TODO: PERF: Should we bind this to a pointer in constructor? */
+    TheISA::TLB *getITBPtr() { return cpu->getITBPtr(); }
 
     /** Returns a pointer to the DTB. */
-    TheISA::TLB *getDTBPtr() { return cpu->dtb; }
+    /** @TODO: PERF: Should we bind this to a pointer in constructor? */
+    TheISA::TLB *getDTBPtr() { return cpu->getDTBPtr(); }
 
     System *getSystemPtr() { return cpu->system; }