lsq.hh revision 8975:7f36d4436074
12207SN/A/* 22207SN/A * Copyright (c) 2011 ARM Limited 32207SN/A * All rights reserved 42207SN/A * 52207SN/A * The license below extends only to copyright in the software and shall 62207SN/A * not be construed as granting a license to any other intellectual 72207SN/A * property including but not limited to intellectual property relating 82207SN/A * to a hardware implementation of the functionality of the software 92207SN/A * licensed hereunder. You may use the software subject to the license 102207SN/A * terms below provided that you ensure that this notice is replicated 112207SN/A * unmodified and in its entirety in all distributions of the software, 122207SN/A * modified or unmodified, in source code or in binary form. 132207SN/A * 142207SN/A * Copyright (c) 2004-2006 The Regents of The University of Michigan 152207SN/A * All rights reserved. 162207SN/A * 172207SN/A * Redistribution and use in source and binary forms, with or without 182207SN/A * modification, are permitted provided that the following conditions are 192207SN/A * met: redistributions of source code must retain the above copyright 202207SN/A * notice, this list of conditions and the following disclaimer; 212207SN/A * redistributions in binary form must reproduce the above copyright 222207SN/A * notice, this list of conditions and the following disclaimer in the 232207SN/A * documentation and/or other materials provided with the distribution; 242207SN/A * neither the name of the copyright holders nor the names of its 252207SN/A * contributors may be used to endorse or promote products derived from 262207SN/A * this software without specific prior written permission. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292665Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302207SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312207SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3211793Sbrandon.potter@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3311793Sbrandon.potter@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342972Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 358229Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362454SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3712334Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 382680Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 398232Snate@binkert.org * 405759Shsul@eecs.umich.edu * Authors: Korey Sewell 4112431Sgabeblack@google.com */ 4211854Sbrandon.potter@amd.com 437678Sgblack@eecs.umich.edu#ifndef __CPU_O3_LSQ_HH__ 445759Shsul@eecs.umich.edu#define __CPU_O3_LSQ_HH__ 4511800Sbrandon.potter@amd.com 462474SN/A#include <map> 472207SN/A#include <queue> 482474SN/A 492474SN/A#include "cpu/o3/lsq_unit.hh" 502474SN/A#include "cpu/inst_seq.hh" 5111851Sbrandon.potter@amd.com#include "mem/port.hh" 5212432Sgabeblack@google.com#include "sim/sim_object.hh" 5312432Sgabeblack@google.com 542474SN/Astruct DerivO3CPUParams; 5512441Sgabeblack@google.com 5611905SBrandon.Potter@amd.comtemplate <class Impl> 5711905SBrandon.Potter@amd.comclass LSQ { 5811905SBrandon.Potter@amd.com public: 592474SN/A typedef typename Impl::O3CPU O3CPU; 602474SN/A typedef typename Impl::DynInstPtr DynInstPtr; 612474SN/A typedef typename Impl::CPUPol::IEW IEW; 6211905SBrandon.Potter@amd.com typedef typename Impl::CPUPol::LSQUnit LSQUnit; 632474SN/A 6411905SBrandon.Potter@amd.com /** SMT policy. */ 6511905SBrandon.Potter@amd.com enum LSQPolicy { 6611905SBrandon.Potter@amd.com Dynamic, 6711905SBrandon.Potter@amd.com Partitioned, 682474SN/A Threshold 692474SN/A }; 7011905SBrandon.Potter@amd.com 712474SN/A /** Constructs an LSQ with the given parameters. */ 7211905SBrandon.Potter@amd.com LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params); 7311905SBrandon.Potter@amd.com 742474SN/A /** Returns the name of the LSQ. */ 752474SN/A std::string name() const; 762474SN/A 7711851Sbrandon.potter@amd.com /** Registers statistics of each LSQ unit. */ 785759Shsul@eecs.umich.edu void regStats(); 7911389Sbrandon.potter@amd.com 8011389Sbrandon.potter@amd.com /** Sets the pointer to the list of active threads. */ 8111389Sbrandon.potter@amd.com void setActiveThreads(std::list<ThreadID> *at_ptr); 825759Shsul@eecs.umich.edu /** Switches out the LSQ. */ 835759Shsul@eecs.umich.edu void switchOut(); 845771Shsul@eecs.umich.edu /** Takes over execution from another CPU's thread. */ 855759Shsul@eecs.umich.edu void takeOverFrom(); 865759Shsul@eecs.umich.edu 875759Shsul@eecs.umich.edu /** Number of entries needed for the given amount of threads.*/ 8811321Ssteve.reinhardt@amd.com int entryAmount(ThreadID num_threads); 895759Shsul@eecs.umich.edu void removeEntries(ThreadID tid); 9011320Ssteve.reinhardt@amd.com /** Reset the max entries for each thread. */ 915759Shsul@eecs.umich.edu void resetEntries(); 925759Shsul@eecs.umich.edu /** Resize the max entries for a thread. */ 935759Shsul@eecs.umich.edu void resizeEntries(unsigned size, ThreadID tid); 945759Shsul@eecs.umich.edu 955759Shsul@eecs.umich.edu /** Ticks the LSQ. */ 965759Shsul@eecs.umich.edu void tick(); 975759Shsul@eecs.umich.edu /** Ticks a specific LSQ Unit. */ 9810318Sandreas.hansson@arm.com void tick(ThreadID tid) 995759Shsul@eecs.umich.edu { thread[tid].tick(); } 1005759Shsul@eecs.umich.edu 1015759Shsul@eecs.umich.edu /** Inserts a load into the LSQ. */ 1025759Shsul@eecs.umich.edu void insertLoad(DynInstPtr &load_inst); 10311389Sbrandon.potter@amd.com /** Inserts a store into the LSQ. */ 10411389Sbrandon.potter@amd.com void insertStore(DynInstPtr &store_inst); 10511389Sbrandon.potter@amd.com 10611389Sbrandon.potter@amd.com /** Executes a load. */ 1075759Shsul@eecs.umich.edu Fault executeLoad(DynInstPtr &inst); 1085759Shsul@eecs.umich.edu 1095759Shsul@eecs.umich.edu /** Executes a store. */ 1105759Shsul@eecs.umich.edu Fault executeStore(DynInstPtr &inst); 1115759Shsul@eecs.umich.edu 1125759Shsul@eecs.umich.edu /** 1135759Shsul@eecs.umich.edu * Commits loads up until the given sequence number for a specific thread. 1145759Shsul@eecs.umich.edu */ 1155759Shsul@eecs.umich.edu void commitLoads(InstSeqNum &youngest_inst, ThreadID tid) 1165759Shsul@eecs.umich.edu { thread[tid].commitLoads(youngest_inst); } 1175759Shsul@eecs.umich.edu 1185759Shsul@eecs.umich.edu /** 1195759Shsul@eecs.umich.edu * Commits stores up until the given sequence number for a specific thread. 1205759Shsul@eecs.umich.edu */ 1216227Snate@binkert.org void commitStores(InstSeqNum &youngest_inst, ThreadID tid) 1225759Shsul@eecs.umich.edu { thread[tid].commitStores(youngest_inst); } 1235759Shsul@eecs.umich.edu 1245759Shsul@eecs.umich.edu /** 1256227Snate@binkert.org * Attempts to write back stores until all cache ports are used or the 1265759Shsul@eecs.umich.edu * interface becomes blocked. 1275759Shsul@eecs.umich.edu */ 1285759Shsul@eecs.umich.edu void writebackStores(); 1295759Shsul@eecs.umich.edu /** Same as above, but only for one thread. */ 13011320Ssteve.reinhardt@amd.com void writebackStores(ThreadID tid); 13111320Ssteve.reinhardt@amd.com 1325759Shsul@eecs.umich.edu /** 13311320Ssteve.reinhardt@amd.com * Squash instructions from a thread until the specified sequence number. 1345759Shsul@eecs.umich.edu */ 1355759Shsul@eecs.umich.edu void squash(const InstSeqNum &squashed_num, ThreadID tid) 1365759Shsul@eecs.umich.edu { thread[tid].squash(squashed_num); } 1375759Shsul@eecs.umich.edu 1385759Shsul@eecs.umich.edu /** Returns whether or not there was a memory ordering violation. */ 1395759Shsul@eecs.umich.edu bool violation(); 14011905SBrandon.Potter@amd.com /** 1415759Shsul@eecs.umich.edu * Returns whether or not there was a memory ordering violation for a 14211905SBrandon.Potter@amd.com * specific thread. 14311905SBrandon.Potter@amd.com */ 1445759Shsul@eecs.umich.edu bool violation(ThreadID tid) 14511905SBrandon.Potter@amd.com { return thread[tid].violation(); } 14611905SBrandon.Potter@amd.com 1475759Shsul@eecs.umich.edu /** Returns if a load is blocked due to the memory system for a specific 1485759Shsul@eecs.umich.edu * thread. 14911905SBrandon.Potter@amd.com */ 1505759Shsul@eecs.umich.edu bool loadBlocked(ThreadID tid) 1515759Shsul@eecs.umich.edu { return thread[tid].loadBlocked(); } 1525759Shsul@eecs.umich.edu 1535759Shsul@eecs.umich.edu bool isLoadBlockedHandled(ThreadID tid) 1545759Shsul@eecs.umich.edu { return thread[tid].isLoadBlockedHandled(); } 1555759Shsul@eecs.umich.edu 1565759Shsul@eecs.umich.edu void setLoadBlockedHandled(ThreadID tid) 1575759Shsul@eecs.umich.edu { thread[tid].setLoadBlockedHandled(); } 1585759Shsul@eecs.umich.edu 1595759Shsul@eecs.umich.edu /** Gets the instruction that caused the memory ordering violation. */ 1605759Shsul@eecs.umich.edu DynInstPtr getMemDepViolator(ThreadID tid) 1615759Shsul@eecs.umich.edu { return thread[tid].getMemDepViolator(); } 1625759Shsul@eecs.umich.edu 1635759Shsul@eecs.umich.edu /** Returns the head index of the load queue for a specific thread. */ 16411905SBrandon.Potter@amd.com int getLoadHead(ThreadID tid) 1655759Shsul@eecs.umich.edu { return thread[tid].getLoadHead(); } 1665759Shsul@eecs.umich.edu 1675759Shsul@eecs.umich.edu /** Returns the sequence number of the head of the load queue. */ 1685759Shsul@eecs.umich.edu InstSeqNum getLoadHeadSeqNum(ThreadID tid) 1695759Shsul@eecs.umich.edu { 1706227Snate@binkert.org return thread[tid].getLoadHeadSeqNum(); 1718852Sandreas.hansson@arm.com } 1725759Shsul@eecs.umich.edu 1738852Sandreas.hansson@arm.com /** Returns the head index of the store queue. */ 1745759Shsul@eecs.umich.edu int getStoreHead(ThreadID tid) 1755759Shsul@eecs.umich.edu { return thread[tid].getStoreHead(); } 1765759Shsul@eecs.umich.edu 1775759Shsul@eecs.umich.edu /** Returns the sequence number of the head of the store queue. */ 1785759Shsul@eecs.umich.edu InstSeqNum getStoreHeadSeqNum(ThreadID tid) 1795958Sgblack@eecs.umich.edu { 1805958Sgblack@eecs.umich.edu return thread[tid].getStoreHeadSeqNum(); 18111905SBrandon.Potter@amd.com } 1825759Shsul@eecs.umich.edu 18311389Sbrandon.potter@amd.com /** Returns the number of instructions in all of the queues. */ 1845759Shsul@eecs.umich.edu int getCount(); 1855759Shsul@eecs.umich.edu /** Returns the number of instructions in the queues of one thread. */ 1865759Shsul@eecs.umich.edu int getCount(ThreadID tid) 18711851Sbrandon.potter@amd.com { return thread[tid].getCount(); } 1882474SN/A 1896820SLisa.Hsu@amd.com /** Returns the total number of loads in the load queue. */ 19011801Sbrandon.potter@amd.com int numLoads(); 1917532Ssteve.reinhardt@amd.com /** Returns the total number of loads for a single thread. */ 1926820SLisa.Hsu@amd.com int numLoads(ThreadID tid) 1935183Ssaidi@eecs.umich.edu { return thread[tid].numLoads(); } 1947532Ssteve.reinhardt@amd.com 19512186Sgabeblack@google.com /** Returns the total number of stores in the store queue. */ 1967532Ssteve.reinhardt@amd.com int numStores(); 19712186Sgabeblack@google.com /** Returns the total number of stores for a single thread. */ 19811801Sbrandon.potter@amd.com int numStores(ThreadID tid) 1997532Ssteve.reinhardt@amd.com { return thread[tid].numStores(); } 2007532Ssteve.reinhardt@amd.com 2017532Ssteve.reinhardt@amd.com /** Returns the total number of loads that are ready. */ 2027532Ssteve.reinhardt@amd.com int numLoadsReady(); 2037532Ssteve.reinhardt@amd.com /** Returns the number of loads that are ready for a single thread. */ 2047532Ssteve.reinhardt@amd.com int numLoadsReady(ThreadID tid) 20511851Sbrandon.potter@amd.com { return thread[tid].numLoadsReady(); } 2067532Ssteve.reinhardt@amd.com 2077532Ssteve.reinhardt@amd.com /** Returns the number of free entries. */ 2087532Ssteve.reinhardt@amd.com unsigned numFreeEntries(); 2097532Ssteve.reinhardt@amd.com /** Returns the number of free entries for a specific thread. */ 2107532Ssteve.reinhardt@amd.com unsigned numFreeEntries(ThreadID tid); 21111851Sbrandon.potter@amd.com 2125759Shsul@eecs.umich.edu /** Returns if the LSQ is full (either LQ or SQ is full). */ 21310318Sandreas.hansson@arm.com bool isFull(); 2142474SN/A /** 2157532Ssteve.reinhardt@amd.com * Returns if the LSQ is full for a specific thread (either LQ or SQ is 2165713Shsul@eecs.umich.edu * full). 2175713Shsul@eecs.umich.edu */ 2187701Sgblack@eecs.umich.edu bool isFull(ThreadID tid); 2197701Sgblack@eecs.umich.edu 2204997Sgblack@eecs.umich.edu /** Returns if any of the LQs are full. */ 2215713Shsul@eecs.umich.edu bool lqFull(); 2222474SN/A /** Returns if the LQ of a given thread is full. */ 2232474SN/A bool lqFull(ThreadID tid); 2245958Sgblack@eecs.umich.edu 22511851Sbrandon.potter@amd.com /** Returns if any of the SQs are full. */ 2265958Sgblack@eecs.umich.edu bool sqFull(); 2275958Sgblack@eecs.umich.edu /** Returns if the SQ of a given thread is full. */ 2286701Sgblack@eecs.umich.edu bool sqFull(ThreadID tid); 2295958Sgblack@eecs.umich.edu 2305958Sgblack@eecs.umich.edu /** 2315958Sgblack@eecs.umich.edu * Returns if the LSQ is stalled due to a memory operation that must be 23211851Sbrandon.potter@amd.com * replayed. 2335958Sgblack@eecs.umich.edu */ 2345958Sgblack@eecs.umich.edu bool isStalled(); 2355958Sgblack@eecs.umich.edu /** 2365958Sgblack@eecs.umich.edu * Returns if the LSQ of a specific thread is stalled due to a memory 2375958Sgblack@eecs.umich.edu * operation that must be replayed. 2385958Sgblack@eecs.umich.edu */ 23911851Sbrandon.potter@amd.com bool isStalled(ThreadID tid); 2405958Sgblack@eecs.umich.edu 2415958Sgblack@eecs.umich.edu /** Returns whether or not there are any stores to write back to memory. */ 2425958Sgblack@eecs.umich.edu bool hasStoresToWB(); 2435958Sgblack@eecs.umich.edu 24410223Ssteve.reinhardt@amd.com /** Returns whether or not a specific thread has any stores to write back 2455958Sgblack@eecs.umich.edu * to memory. 2465958Sgblack@eecs.umich.edu */ 24710223Ssteve.reinhardt@amd.com bool hasStoresToWB(ThreadID tid) 2485958Sgblack@eecs.umich.edu { return thread[tid].hasStoresToWB(); } 2495958Sgblack@eecs.umich.edu 2505958Sgblack@eecs.umich.edu /** Returns the number of stores a specific thread has to write back. */ 25110223Ssteve.reinhardt@amd.com int numStoresToWB(ThreadID tid) 2525958Sgblack@eecs.umich.edu { return thread[tid].numStoresToWB(); } 2535958Sgblack@eecs.umich.edu 254 /** Returns if the LSQ will write back to memory this cycle. */ 255 bool willWB(); 256 /** Returns if the LSQ of a specific thread will write back to memory this 257 * cycle. 258 */ 259 bool willWB(ThreadID tid) 260 { return thread[tid].willWB(); } 261 262 /** Returns if the cache is currently blocked. */ 263 bool cacheBlocked() 264 { return retryTid != InvalidThreadID; } 265 266 /** Sets the retry thread id, indicating that one of the LSQUnits 267 * tried to access the cache but the cache was blocked. */ 268 void setRetryTid(ThreadID tid) 269 { retryTid = tid; } 270 271 /** Debugging function to print out all instructions. */ 272 void dumpInsts(); 273 /** Debugging function to print out instructions from a specific thread. */ 274 void dumpInsts(ThreadID tid) 275 { thread[tid].dumpInsts(); } 276 277 /** Executes a read operation, using the load specified at the load 278 * index. 279 */ 280 Fault read(RequestPtr req, RequestPtr sreqLow, RequestPtr sreqHigh, 281 uint8_t *data, int load_idx); 282 283 /** Executes a store operation, using the store specified at the store 284 * index. 285 */ 286 Fault write(RequestPtr req, RequestPtr sreqLow, RequestPtr sreqHigh, 287 uint8_t *data, int store_idx); 288 289 /** 290 * Retry the previous send that failed. 291 */ 292 void recvRetry(); 293 294 /** 295 * Handles writing back and completing the load or store that has 296 * returned from memory. 297 * 298 * @param pkt Response packet from the memory sub-system 299 */ 300 bool recvTimingResp(PacketPtr pkt); 301 302 void recvTimingSnoopReq(PacketPtr pkt); 303 304 /** The CPU pointer. */ 305 O3CPU *cpu; 306 307 /** The IEW stage pointer. */ 308 IEW *iewStage; 309 310 protected: 311 /** The LSQ policy for SMT mode. */ 312 LSQPolicy lsqPolicy; 313 314 /** The LSQ units for individual threads. */ 315 LSQUnit thread[Impl::MaxThreads]; 316 317 /** List of Active Threads in System. */ 318 std::list<ThreadID> *activeThreads; 319 320 /** Total Size of LQ Entries. */ 321 unsigned LQEntries; 322 /** Total Size of SQ Entries. */ 323 unsigned SQEntries; 324 325 /** Max LQ Size - Used to Enforce Sharing Policies. */ 326 unsigned maxLQEntries; 327 328 /** Max SQ Size - Used to Enforce Sharing Policies. */ 329 unsigned maxSQEntries; 330 331 /** Number of Threads. */ 332 ThreadID numThreads; 333 334 /** The thread id of the LSQ Unit that is currently waiting for a 335 * retry. */ 336 ThreadID retryTid; 337}; 338 339template <class Impl> 340Fault 341LSQ<Impl>::read(RequestPtr req, RequestPtr sreqLow, RequestPtr sreqHigh, 342 uint8_t *data, int load_idx) 343{ 344 ThreadID tid = req->threadId(); 345 346 return thread[tid].read(req, sreqLow, sreqHigh, data, load_idx); 347} 348 349template <class Impl> 350Fault 351LSQ<Impl>::write(RequestPtr req, RequestPtr sreqLow, RequestPtr sreqHigh, 352 uint8_t *data, int store_idx) 353{ 354 ThreadID tid = req->threadId(); 355 356 return thread[tid].write(req, sreqLow, sreqHigh, data, store_idx); 357} 358 359#endif // __CPU_O3_LSQ_HH__ 360