lsq.hh revision 5489:94a7bb476fca
12381SN/A/* 22592SN/A * Copyright (c) 2004-2006 The Regents of The University of Michigan 37465Ssteve.reinhardt@amd.com * All rights reserved. 42381SN/A * 52381SN/A * Redistribution and use in source and binary forms, with or without 62381SN/A * modification, are permitted provided that the following conditions are 72381SN/A * met: redistributions of source code must retain the above copyright 82381SN/A * notice, this list of conditions and the following disclaimer; 92381SN/A * redistributions in binary form must reproduce the above copyright 102381SN/A * notice, this list of conditions and the following disclaimer in the 112381SN/A * documentation and/or other materials provided with the distribution; 122381SN/A * neither the name of the copyright holders nor the names of its 132381SN/A * contributors may be used to endorse or promote products derived from 142381SN/A * this software without specific prior written permission. 152381SN/A * 162381SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172381SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182381SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192381SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202381SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212381SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222381SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232381SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242381SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252381SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262381SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272381SN/A * 282665Ssaidi@eecs.umich.edu * Authors: Korey Sewell 292665Ssaidi@eecs.umich.edu */ 302665Ssaidi@eecs.umich.edu 312665Ssaidi@eecs.umich.edu#ifndef __CPU_O3_LSQ_HH__ 322381SN/A#define __CPU_O3_LSQ_HH__ 332381SN/A 342381SN/A#include <map> 352381SN/A#include <queue> 362662Sstever@eecs.umich.edu 372381SN/A#include "config/full_system.hh" 382381SN/A#include "cpu/inst_seq.hh" 392381SN/A#include "cpu/o3/lsq_unit.hh" 402381SN/A#include "mem/port.hh" 412381SN/A#include "sim/sim_object.hh" 423348Sbinkertn@umich.edu 433348Sbinkertn@umich.edutemplate <class Impl> 444022Sstever@eecs.umich.educlass LSQ { 453348Sbinkertn@umich.edu public: 465735Snate@binkert.org typedef typename Impl::Params Params; 474024Sbinkertn@umich.edu typedef typename Impl::O3CPU O3CPU; 484610Ssaidi@eecs.umich.edu typedef typename Impl::DynInstPtr DynInstPtr; 495735Snate@binkert.org typedef typename Impl::CPUPol::IEW IEW; 503940Ssaidi@eecs.umich.edu typedef typename Impl::CPUPol::LSQUnit LSQUnit; 515314Sstever@gmail.com 526216Snate@binkert.org /** SMT policy. */ 532392SN/A enum LSQPolicy { 544167Sbinkertn@umich.edu Dynamic, 552394SN/A Partitioned, 562394SN/A Threshold 573349Sbinkertn@umich.edu }; 582394SN/A 592812Srdreslin@umich.edu /** Constructs an LSQ with the given parameters. */ 602812Srdreslin@umich.edu LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, Params *params); 614022Sstever@eecs.umich.edu 624022Sstever@eecs.umich.edu /** Returns the name of the LSQ. */ 635735Snate@binkert.org std::string name() const; 645735Snate@binkert.org 654022Sstever@eecs.umich.edu /** Registers statistics of each LSQ unit. */ 665735Snate@binkert.org void regStats(); 675735Snate@binkert.org 685735Snate@binkert.org /** Returns dcache port. 694022Sstever@eecs.umich.edu * @todo: Dcache port needs to be moved up to this level for SMT 704022Sstever@eecs.umich.edu * to work. For now it just returns the port from one of the 714022Sstever@eecs.umich.edu * threads. 724022Sstever@eecs.umich.edu */ 734473Sstever@eecs.umich.edu Port *getDcachePort() { return &dcachePort; } 745319Sstever@gmail.com 754022Sstever@eecs.umich.edu /** Sets the pointer to the list of active threads. */ 764022Sstever@eecs.umich.edu void setActiveThreads(std::list<unsigned> *at_ptr); 774022Sstever@eecs.umich.edu /** Switches out the LSQ. */ 784022Sstever@eecs.umich.edu void switchOut(); 794022Sstever@eecs.umich.edu /** Takes over execution from another CPU's thread. */ 804022Sstever@eecs.umich.edu void takeOverFrom(); 814022Sstever@eecs.umich.edu 824022Sstever@eecs.umich.edu /** Number of entries needed for the given amount of threads.*/ 834022Sstever@eecs.umich.edu int entryAmount(int num_threads); 844022Sstever@eecs.umich.edu void removeEntries(unsigned tid); 857465Ssteve.reinhardt@amd.com /** Reset the max entries for each thread. */ 864628Sstever@eecs.umich.edu void resetEntries(); 877465Ssteve.reinhardt@amd.com /** Resize the max entries for a thread. */ 887465Ssteve.reinhardt@amd.com void resizeEntries(unsigned size, unsigned tid); 894022Sstever@eecs.umich.edu 904022Sstever@eecs.umich.edu /** Ticks the LSQ. */ 914626Sstever@eecs.umich.edu void tick(); 924626Sstever@eecs.umich.edu /** Ticks a specific LSQ Unit. */ 934626Sstever@eecs.umich.edu void tick(unsigned tid) 944040Ssaidi@eecs.umich.edu { thread[tid].tick(); } 954040Ssaidi@eecs.umich.edu 965650Sgblack@eecs.umich.edu /** Inserts a load into the LSQ. */ 975650Sgblack@eecs.umich.edu void insertLoad(DynInstPtr &load_inst); 984870Sstever@eecs.umich.edu /** Inserts a store into the LSQ. */ 994870Sstever@eecs.umich.edu void insertStore(DynInstPtr &store_inst); 1004870Sstever@eecs.umich.edu 1014870Sstever@eecs.umich.edu /** Executes a load. */ 1024870Sstever@eecs.umich.edu Fault executeLoad(DynInstPtr &inst); 1034870Sstever@eecs.umich.edu 1044870Sstever@eecs.umich.edu /** Executes a store. */ 1055314Sstever@gmail.com Fault executeStore(DynInstPtr &inst); 1065314Sstever@gmail.com 1074022Sstever@eecs.umich.edu /** 1084022Sstever@eecs.umich.edu * Commits loads up until the given sequence number for a specific thread. 1094022Sstever@eecs.umich.edu */ 1104022Sstever@eecs.umich.edu void commitLoads(InstSeqNum &youngest_inst, unsigned tid) 1115735Snate@binkert.org { thread[tid].commitLoads(youngest_inst); } 1125735Snate@binkert.org 1135735Snate@binkert.org /** 1144022Sstever@eecs.umich.edu * Commits stores up until the given sequence number for a specific thread. 1154022Sstever@eecs.umich.edu */ 1164626Sstever@eecs.umich.edu void commitStores(InstSeqNum &youngest_inst, unsigned tid) 1174626Sstever@eecs.umich.edu { thread[tid].commitStores(youngest_inst); } 1187465Ssteve.reinhardt@amd.com 1194626Sstever@eecs.umich.edu /** 1204022Sstever@eecs.umich.edu * Attempts to write back stores until all cache ports are used or the 1214626Sstever@eecs.umich.edu * interface becomes blocked. 1224626Sstever@eecs.umich.edu */ 1234626Sstever@eecs.umich.edu void writebackStores(); 1244626Sstever@eecs.umich.edu /** Same as above, but only for one thread. */ 1254022Sstever@eecs.umich.edu void writebackStores(unsigned tid); 1264022Sstever@eecs.umich.edu 1276076Sgblack@eecs.umich.edu /** 1284626Sstever@eecs.umich.edu * Squash instructions from a thread until the specified sequence number. 1294870Sstever@eecs.umich.edu */ 1305314Sstever@gmail.com void squash(const InstSeqNum &squashed_num, unsigned tid) 1314022Sstever@eecs.umich.edu { thread[tid].squash(squashed_num); } 1324022Sstever@eecs.umich.edu 1334022Sstever@eecs.umich.edu /** Returns whether or not there was a memory ordering violation. */ 1345735Snate@binkert.org bool violation(); 1355735Snate@binkert.org /** 1365735Snate@binkert.org * Returns whether or not there was a memory ordering violation for a 1375735Snate@binkert.org * specific thread. 1385735Snate@binkert.org */ 1395735Snate@binkert.org bool violation(unsigned tid) 1405735Snate@binkert.org { return thread[tid].violation(); } 1414022Sstever@eecs.umich.edu 1425735Snate@binkert.org /** Returns if a load is blocked due to the memory system for a specific 1435735Snate@binkert.org * thread. 1444022Sstever@eecs.umich.edu */ 1455735Snate@binkert.org bool loadBlocked(unsigned tid) 1464022Sstever@eecs.umich.edu { return thread[tid].loadBlocked(); } 1474022Sstever@eecs.umich.edu 1484022Sstever@eecs.umich.edu bool isLoadBlockedHandled(unsigned tid) 1495735Snate@binkert.org { return thread[tid].isLoadBlockedHandled(); } 1504022Sstever@eecs.umich.edu 1514022Sstever@eecs.umich.edu void setLoadBlockedHandled(unsigned tid) 1524022Sstever@eecs.umich.edu { thread[tid].setLoadBlockedHandled(); } 1534022Sstever@eecs.umich.edu 1544022Sstever@eecs.umich.edu /** Gets the instruction that caused the memory ordering violation. */ 1554022Sstever@eecs.umich.edu DynInstPtr getMemDepViolator(unsigned tid) 1565735Snate@binkert.org { return thread[tid].getMemDepViolator(); } 1575735Snate@binkert.org 1585735Snate@binkert.org /** Returns the head index of the load queue for a specific thread. */ 1594022Sstever@eecs.umich.edu int getLoadHead(unsigned tid) 1604022Sstever@eecs.umich.edu { return thread[tid].getLoadHead(); } 1614022Sstever@eecs.umich.edu 1624022Sstever@eecs.umich.edu /** Returns the sequence number of the head of the load queue. */ 1634022Sstever@eecs.umich.edu InstSeqNum getLoadHeadSeqNum(unsigned tid) 1644022Sstever@eecs.umich.edu { 1657465Ssteve.reinhardt@amd.com return thread[tid].getLoadHeadSeqNum(); 1667465Ssteve.reinhardt@amd.com } 1674022Sstever@eecs.umich.edu 1684022Sstever@eecs.umich.edu /** Returns the head index of the store queue. */ 1694870Sstever@eecs.umich.edu int getStoreHead(unsigned tid) 1704022Sstever@eecs.umich.edu { return thread[tid].getStoreHead(); } 1714022Sstever@eecs.umich.edu 1724022Sstever@eecs.umich.edu /** Returns the sequence number of the head of the store queue. */ 1734626Sstever@eecs.umich.edu InstSeqNum getStoreHeadSeqNum(unsigned tid) 1746102Sgblack@eecs.umich.edu { 1754870Sstever@eecs.umich.edu return thread[tid].getStoreHeadSeqNum(); 1765314Sstever@gmail.com } 1774022Sstever@eecs.umich.edu 1785735Snate@binkert.org /** Returns the number of instructions in all of the queues. */ 1795735Snate@binkert.org int getCount(); 1805735Snate@binkert.org /** Returns the number of instructions in the queues of one thread. */ 1814022Sstever@eecs.umich.edu int getCount(unsigned tid) 1824022Sstever@eecs.umich.edu { return thread[tid].getCount(); } 1834022Sstever@eecs.umich.edu 1845735Snate@binkert.org /** Returns the total number of loads in the load queue. */ 1855735Snate@binkert.org int numLoads(); 1864022Sstever@eecs.umich.edu /** Returns the total number of loads for a single thread. */ 1874022Sstever@eecs.umich.edu int numLoads(unsigned tid) 1885735Snate@binkert.org { return thread[tid].numLoads(); } 1895735Snate@binkert.org 1905735Snate@binkert.org /** Returns the total number of stores in the store queue. */ 1914022Sstever@eecs.umich.edu int numStores(); 1925735Snate@binkert.org /** Returns the total number of stores for a single thread. */ 1935735Snate@binkert.org int numStores(unsigned tid) 1944022Sstever@eecs.umich.edu { return thread[tid].numStores(); } 1954022Sstever@eecs.umich.edu 1962381SN/A /** Returns the total number of loads that are ready. */ 1972662Sstever@eecs.umich.edu int numLoadsReady(); 1982662Sstever@eecs.umich.edu /** Returns the number of loads that are ready for a single thread. */ 1992662Sstever@eecs.umich.edu int numLoadsReady(unsigned tid) 2002662Sstever@eecs.umich.edu { return thread[tid].numLoadsReady(); } 2012662Sstever@eecs.umich.edu 2022381SN/A /** Returns the number of free entries. */ 2035314Sstever@gmail.com unsigned numFreeEntries(); 2042381SN/A /** Returns the number of free entries for a specific thread. */ 2052813Srdreslin@umich.edu unsigned numFreeEntries(unsigned tid); 2065735Snate@binkert.org 2075735Snate@binkert.org /** Returns if the LSQ is full (either LQ or SQ is full). */ 2085735Snate@binkert.org bool isFull(); 2094022Sstever@eecs.umich.edu /** 2105735Snate@binkert.org * Returns if the LSQ is full for a specific thread (either LQ or SQ is 2115735Snate@binkert.org * full). 2125735Snate@binkert.org */ 2135735Snate@binkert.org bool isFull(unsigned tid); 2145735Snate@binkert.org 2155735Snate@binkert.org /** Returns if any of the LQs are full. */ 2165735Snate@binkert.org bool lqFull(); 2175735Snate@binkert.org /** Returns if the LQ of a given thread is full. */ 2185735Snate@binkert.org bool lqFull(unsigned tid); 2195735Snate@binkert.org 2205735Snate@binkert.org /** Returns if any of the SQs are full. */ 2215735Snate@binkert.org bool sqFull(); 2225735Snate@binkert.org /** Returns if the SQ of a given thread is full. */ 2235735Snate@binkert.org bool sqFull(unsigned tid); 2245735Snate@binkert.org 2255735Snate@binkert.org /** 2265735Snate@binkert.org * Returns if the LSQ is stalled due to a memory operation that must be 2275735Snate@binkert.org * replayed. 2285735Snate@binkert.org */ 2295735Snate@binkert.org bool isStalled(); 2305735Snate@binkert.org /** 2315735Snate@binkert.org * Returns if the LSQ of a specific thread is stalled due to a memory 2325735Snate@binkert.org * operation that must be replayed. 2335735Snate@binkert.org */ 2345735Snate@binkert.org bool isStalled(unsigned tid); 2355735Snate@binkert.org 2365735Snate@binkert.org /** Returns whether or not there are any stores to write back to memory. */ 2375735Snate@binkert.org bool hasStoresToWB(); 2385735Snate@binkert.org 2395735Snate@binkert.org /** Returns whether or not a specific thread has any stores to write back 2405735Snate@binkert.org * to memory. 2415735Snate@binkert.org */ 2425735Snate@binkert.org bool hasStoresToWB(unsigned tid) 2434022Sstever@eecs.umich.edu { return thread[tid].hasStoresToWB(); } 2444022Sstever@eecs.umich.edu 2455735Snate@binkert.org /** Returns the number of stores a specific thread has to write back. */ 2464870Sstever@eecs.umich.edu int numStoresToWB(unsigned tid) 2474870Sstever@eecs.umich.edu { return thread[tid].numStoresToWB(); } 2485735Snate@binkert.org 2494870Sstever@eecs.umich.edu /** Returns if the LSQ will write back to memory this cycle. */ 2504870Sstever@eecs.umich.edu bool willWB(); 2512566SN/A /** Returns if the LSQ of a specific thread will write back to memory this 2525735Snate@binkert.org * cycle. 2535735Snate@binkert.org */ 2545735Snate@binkert.org bool willWB(unsigned tid) 2555735Snate@binkert.org { return thread[tid].willWB(); } 2565735Snate@binkert.org 2575735Snate@binkert.org /** Returns if the cache is currently blocked. */ 2582566SN/A bool cacheBlocked() 2592566SN/A { return retryTid != -1; } 2602566SN/A 2615735Snate@binkert.org /** Sets the retry thread id, indicating that one of the LSQUnits 2625735Snate@binkert.org * tried to access the cache but the cache was blocked. */ 2632381SN/A void setRetryTid(int tid) 2642381SN/A { retryTid = tid; } 2655735Snate@binkert.org 2666227Snate@binkert.org /** Debugging function to print out all instructions. */ 2672381SN/A void dumpInsts(); 2685735Snate@binkert.org /** Debugging function to print out instructions from a specific thread. */ 2695735Snate@binkert.org void dumpInsts(unsigned tid) 2705735Snate@binkert.org { thread[tid].dumpInsts(); } 2715735Snate@binkert.org 2725735Snate@binkert.org /** Executes a read operation, using the load specified at the load index. */ 2735735Snate@binkert.org template <class T> 2745735Snate@binkert.org Fault read(RequestPtr req, T &data, int load_idx); 2752381SN/A 2765735Snate@binkert.org /** Executes a store operation, using the store specified at the store 2775735Snate@binkert.org * index. 2785735Snate@binkert.org */ 2795735Snate@binkert.org template <class T> 2805735Snate@binkert.org Fault write(RequestPtr req, T &data, int store_idx); 2815735Snate@binkert.org 2825735Snate@binkert.org /** The CPU pointer. */ 2835735Snate@binkert.org O3CPU *cpu; 2842641Sstever@eecs.umich.edu 2855735Snate@binkert.org /** The IEW stage pointer. */ 2865735Snate@binkert.org IEW *iewStage; 2874870Sstever@eecs.umich.edu 2884870Sstever@eecs.umich.edu /** DcachePort class for this LSQ. Handles doing the 2894870Sstever@eecs.umich.edu * communication with the cache/memory. 2904870Sstever@eecs.umich.edu */ 2914870Sstever@eecs.umich.edu class DcachePort : public Port 2924870Sstever@eecs.umich.edu { 2932641Sstever@eecs.umich.edu protected: 2945735Snate@binkert.org /** Pointer to LSQ. */ 2952811Srdreslin@umich.edu LSQ *lsq; 2962811Srdreslin@umich.edu 2975735Snate@binkert.org public: 2983218Sgblack@eecs.umich.edu /** Default constructor. */ 2993218Sgblack@eecs.umich.edu DcachePort(LSQ *_lsq, O3CPU *_cpu) 3005735Snate@binkert.org : Port(_lsq->name() + "-dport", _cpu), lsq(_lsq) 3013218Sgblack@eecs.umich.edu { } 3023218Sgblack@eecs.umich.edu 3035735Snate@binkert.org bool snoopRangeSent; 3045735Snate@binkert.org 3055735Snate@binkert.org virtual void setPeer(Port *port); 3062623SN/A 3075735Snate@binkert.org protected: 3085735Snate@binkert.org /** Atomic version of receive. Panics. */ 3095735Snate@binkert.org virtual Tick recvAtomic(PacketPtr pkt); 3105735Snate@binkert.org 3115735Snate@binkert.org /** Functional version of receive. Panics. */ 3125735Snate@binkert.org virtual void recvFunctional(PacketPtr pkt); 3135735Snate@binkert.org 3145735Snate@binkert.org /** Receives status change. Other than range changing, panics. */ 3155735Snate@binkert.org virtual void recvStatusChange(Status status); 3165735Snate@binkert.org 3175735Snate@binkert.org /** Returns the address ranges of this device. */ 3182641Sstever@eecs.umich.edu virtual void getDeviceAddressRanges(AddrRangeList &resp, 3192641Sstever@eecs.umich.edu bool &snoop) 3202641Sstever@eecs.umich.edu { resp.clear(); snoop = true; } 3215315Sstever@gmail.com 3225315Sstever@gmail.com /** Timing version of receive. Handles writing back and 3235315Sstever@gmail.com * completing the load or store that has returned from 3245315Sstever@gmail.com * memory. */ 3255735Snate@binkert.org virtual bool recvTiming(PacketPtr pkt); 3265735Snate@binkert.org 3275735Snate@binkert.org /** Handles doing a retry of the previous send. */ 3285735Snate@binkert.org virtual void recvRetry(); 3295735Snate@binkert.org }; 3305735Snate@binkert.org 3315735Snate@binkert.org /** D-cache port. */ 3325735Snate@binkert.org DcachePort dcachePort; 3335314Sstever@gmail.com 3345314Sstever@gmail.com#if FULL_SYSTEM 3355314Sstever@gmail.com /** Tell the CPU to update the Phys and Virt ports. */ 3365735Snate@binkert.org void updateMemPorts() { cpu->updateMemPorts(); } 3375314Sstever@gmail.com#endif 3385314Sstever@gmail.com 3395314Sstever@gmail.com protected: 3405314Sstever@gmail.com /** The LSQ policy for SMT mode. */ 3415314Sstever@gmail.com LSQPolicy lsqPolicy; 3425314Sstever@gmail.com 3435314Sstever@gmail.com /** The LSQ units for individual threads. */ 3445314Sstever@gmail.com LSQUnit thread[Impl::MaxThreads]; 3455314Sstever@gmail.com 3465314Sstever@gmail.com /** List of Active Threads in System. */ 3475314Sstever@gmail.com std::list<unsigned> *activeThreads; 3485314Sstever@gmail.com 3495314Sstever@gmail.com /** Total Size of LQ Entries. */ 3505314Sstever@gmail.com unsigned LQEntries; 3515735Snate@binkert.org /** Total Size of SQ Entries. */ 3525735Snate@binkert.org unsigned SQEntries; 3535735Snate@binkert.org 3545314Sstever@gmail.com /** Max LQ Size - Used to Enforce Sharing Policies. */ 3555315Sstever@gmail.com unsigned maxLQEntries; 3565735Snate@binkert.org 3575735Snate@binkert.org /** Max SQ Size - Used to Enforce Sharing Policies. */ 3585315Sstever@gmail.com unsigned maxSQEntries; 3595735Snate@binkert.org 3605735Snate@binkert.org /** Number of Threads. */ 3615314Sstever@gmail.com unsigned numThreads; 3625314Sstever@gmail.com 3635735Snate@binkert.org /** The thread id of the LSQ Unit that is currently waiting for a 3645735Snate@binkert.org * retry. */ 3655735Snate@binkert.org int retryTid; 3665735Snate@binkert.org}; 3675314Sstever@gmail.com 3685735Snate@binkert.orgtemplate <class Impl> 3695735Snate@binkert.orgtemplate <class T> 3705735Snate@binkert.orgFault 3715315Sstever@gmail.comLSQ<Impl>::read(RequestPtr req, T &data, int load_idx) 3725735Snate@binkert.org{ 3735735Snate@binkert.org unsigned tid = req->getThreadNum(); 3745314Sstever@gmail.com 3755735Snate@binkert.org return thread[tid].read(req, data, load_idx); 3765735Snate@binkert.org} 3775735Snate@binkert.org 3785735Snate@binkert.orgtemplate <class Impl> 3795735Snate@binkert.orgtemplate <class T> 3805314Sstever@gmail.comFault 3815314Sstever@gmail.comLSQ<Impl>::write(RequestPtr req, T &data, int store_idx) 3825314Sstever@gmail.com{ 3835735Snate@binkert.org unsigned tid = req->getThreadNum(); 3845735Snate@binkert.org 3855735Snate@binkert.org return thread[tid].write(req, data, store_idx); 3865735Snate@binkert.org} 3875735Snate@binkert.org 3885735Snate@binkert.org#endif // __CPU_O3_LSQ_HH__ 3895735Snate@binkert.org