lsq.hh revision 2348
17119Sgblack@eecs.umich.edu/* 27119Sgblack@eecs.umich.edu * Copyright (c) 2004-2006 The Regents of The University of Michigan 310037SARM gem5 Developers * All rights reserved. 47119Sgblack@eecs.umich.edu * 57119Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 67119Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 77119Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 87119Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 97119Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 107119Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 117119Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 127119Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 137119Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 147119Sgblack@eecs.umich.edu * this software without specific prior written permission. 157119Sgblack@eecs.umich.edu * 167119Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177119Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187119Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197119Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207119Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217119Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 227119Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237119Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247119Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257119Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267119Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277119Sgblack@eecs.umich.edu */ 287119Sgblack@eecs.umich.edu 297119Sgblack@eecs.umich.edu#ifndef __CPU_O3_LSQ_HH__ 307119Sgblack@eecs.umich.edu#define __CPU_O3_LSQ_HH__ 317119Sgblack@eecs.umich.edu 327119Sgblack@eecs.umich.edu#include <map> 337119Sgblack@eecs.umich.edu#include <queue> 347119Sgblack@eecs.umich.edu 357119Sgblack@eecs.umich.edu#include "config/full_system.hh" 367119Sgblack@eecs.umich.edu#include "cpu/inst_seq.hh" 377119Sgblack@eecs.umich.edu//#include "cpu/o3/cpu_policy.hh" 387119Sgblack@eecs.umich.edu#include "cpu/o3/lsq_unit.hh" 397119Sgblack@eecs.umich.edu#include "mem/mem_interface.hh" 407119Sgblack@eecs.umich.edu//#include "mem/page_table.hh" 417119Sgblack@eecs.umich.edu#include "sim/sim_object.hh" 427590Sgblack@eecs.umich.edu 437590Sgblack@eecs.umich.edutemplate <class Impl> 447590Sgblack@eecs.umich.educlass LSQ { 457590Sgblack@eecs.umich.edu public: 467590Sgblack@eecs.umich.edu typedef typename Impl::Params Params; 477590Sgblack@eecs.umich.edu typedef typename Impl::FullCPU FullCPU; 487590Sgblack@eecs.umich.edu typedef typename Impl::DynInstPtr DynInstPtr; 497205Sgblack@eecs.umich.edu typedef typename Impl::CPUPol::IEW IEW; 507590Sgblack@eecs.umich.edu typedef typename Impl::CPUPol::LSQUnit LSQUnit; 5110037SARM gem5 Developers 5210037SARM gem5 Developers /** SMT policy. */ 537590Sgblack@eecs.umich.edu enum LSQPolicy { 547590Sgblack@eecs.umich.edu Dynamic, 557590Sgblack@eecs.umich.edu Partitioned, 567119Sgblack@eecs.umich.edu Threshold 577590Sgblack@eecs.umich.edu }; 587205Sgblack@eecs.umich.edu 597590Sgblack@eecs.umich.edu /** Constructs an LSQ with the given parameters. */ 607590Sgblack@eecs.umich.edu LSQ(Params *params); 617590Sgblack@eecs.umich.edu 627590Sgblack@eecs.umich.edu /** Returns the name of the LSQ. */ 637119Sgblack@eecs.umich.edu std::string name() const; 647590Sgblack@eecs.umich.edu 657119Sgblack@eecs.umich.edu /** Sets the pointer to the list of active threads. */ 6610037SARM gem5 Developers void setActiveThreads(std::list<unsigned> *at_ptr); 6710037SARM gem5 Developers /** Sets the CPU pointer. */ 6810037SARM gem5 Developers void setCPU(FullCPU *cpu_ptr); 6910037SARM gem5 Developers /** Sets the IEW stage pointer. */ 7010037SARM gem5 Developers void setIEW(IEW *iew_ptr); 7110037SARM gem5 Developers /** Sets the page table pointer. */ 7210037SARM gem5 Developers// void setPageTable(PageTable *pt_ptr); 7310037SARM gem5 Developers /** Switches out the LSQ. */ 7410037SARM gem5 Developers void switchOut(); 7510037SARM gem5 Developers /** Takes over execution from another CPU's thread. */ 7610037SARM gem5 Developers void takeOverFrom(); 7710037SARM gem5 Developers 7810037SARM gem5 Developers /** Number of entries needed for the given amount of threads.*/ 7910037SARM gem5 Developers int entryAmount(int num_threads); 8010037SARM gem5 Developers void removeEntries(unsigned tid); 8110037SARM gem5 Developers /** Reset the max entries for each thread. */ 827646Sgene.wu@arm.com void resetEntries(); 837646Sgene.wu@arm.com /** Resize the max entries for a thread. */ 847646Sgene.wu@arm.com void resizeEntries(unsigned size, unsigned tid); 858140SMatt.Horsnell@arm.com 868140SMatt.Horsnell@arm.com /** Ticks the LSQ. */ 878140SMatt.Horsnell@arm.com void tick(); 887646Sgene.wu@arm.com /** Ticks a specific LSQ Unit. */ 897646Sgene.wu@arm.com void tick(unsigned tid) 908140SMatt.Horsnell@arm.com { thread[tid].tick(); } 918140SMatt.Horsnell@arm.com 928140SMatt.Horsnell@arm.com /** Inserts a load into the LSQ. */ 938140SMatt.Horsnell@arm.com void insertLoad(DynInstPtr &load_inst); 948140SMatt.Horsnell@arm.com /** Inserts a store into the LSQ. */ 958140SMatt.Horsnell@arm.com void insertStore(DynInstPtr &store_inst); 968140SMatt.Horsnell@arm.com 978140SMatt.Horsnell@arm.com /** Executes a load. */ 988140SMatt.Horsnell@arm.com Fault executeLoad(DynInstPtr &inst); 997646Sgene.wu@arm.com 1007646Sgene.wu@arm.com /** Executes a store. */ 1018140SMatt.Horsnell@arm.com Fault executeStore(DynInstPtr &inst); 1027646Sgene.wu@arm.com 1038140SMatt.Horsnell@arm.com /** 1048140SMatt.Horsnell@arm.com * Commits loads up until the given sequence number for a specific thread. 1058203SAli.Saidi@ARM.com */ 1068203SAli.Saidi@ARM.com void commitLoads(InstSeqNum &youngest_inst, unsigned tid) 1078203SAli.Saidi@ARM.com { thread[tid].commitLoads(youngest_inst); } 1088203SAli.Saidi@ARM.com 1097119Sgblack@eecs.umich.edu /** 1107646Sgene.wu@arm.com * Commits stores up until the given sequence number for a specific thread. 1117646Sgene.wu@arm.com */ 1127646Sgene.wu@arm.com void commitStores(InstSeqNum &youngest_inst, unsigned tid) 1137646Sgene.wu@arm.com { thread[tid].commitStores(youngest_inst); } 1147646Sgene.wu@arm.com 1157646Sgene.wu@arm.com /** 1167646Sgene.wu@arm.com * Attempts to write back stores until all cache ports are used or the 1177646Sgene.wu@arm.com * interface becomes blocked. 1187646Sgene.wu@arm.com */ 1198140SMatt.Horsnell@arm.com void writebackStores(); 1207646Sgene.wu@arm.com /** Same as above, but only for one thread. */ 1217646Sgene.wu@arm.com void writebackStores(unsigned tid); 1228140SMatt.Horsnell@arm.com 1237646Sgene.wu@arm.com /** 1248140SMatt.Horsnell@arm.com * Squash instructions from a thread until the specified sequence number. 1258140SMatt.Horsnell@arm.com */ 1268203SAli.Saidi@ARM.com void squash(const InstSeqNum &squashed_num, unsigned tid) 12710037SARM gem5 Developers { thread[tid].squash(squashed_num); } 1288203SAli.Saidi@ARM.com 1297646Sgene.wu@arm.com /** Returns whether or not there was a memory ordering violation. */ 1307646Sgene.wu@arm.com bool violation(); 1317646Sgene.wu@arm.com /** 1327646Sgene.wu@arm.com * Returns whether or not there was a memory ordering violation for a 1337646Sgene.wu@arm.com * specific thread. 1347646Sgene.wu@arm.com */ 1357646Sgene.wu@arm.com bool violation(unsigned tid) 1367646Sgene.wu@arm.com { return thread[tid].violation(); } 1377119Sgblack@eecs.umich.edu 1387422Sgblack@eecs.umich.edu /** Returns if a load is blocked due to the memory system for a specific 1398303SAli.Saidi@ARM.com * thread. 1408304SAli.Saidi@ARM.com */ 1418303SAli.Saidi@ARM.com bool loadBlocked(unsigned tid) 1428304SAli.Saidi@ARM.com { return thread[tid].loadBlocked(); } 1438304SAli.Saidi@ARM.com 1448304SAli.Saidi@ARM.com bool isLoadBlockedHandled(unsigned tid) 1458304SAli.Saidi@ARM.com { return thread[tid].isLoadBlockedHandled(); } 1468304SAli.Saidi@ARM.com 1478304SAli.Saidi@ARM.com void setLoadBlockedHandled(unsigned tid) 1488304SAli.Saidi@ARM.com { thread[tid].setLoadBlockedHandled(); } 1498303SAli.Saidi@ARM.com 1508304SAli.Saidi@ARM.com /** Gets the instruction that caused the memory ordering violation. */ 1518304SAli.Saidi@ARM.com DynInstPtr getMemDepViolator(unsigned tid) 1528304SAli.Saidi@ARM.com { return thread[tid].getMemDepViolator(); } 1538304SAli.Saidi@ARM.com 1548304SAli.Saidi@ARM.com /** Returns the head index of the load queue for a specific thread. */ 1558303SAli.Saidi@ARM.com int getLoadHead(unsigned tid) 1568303SAli.Saidi@ARM.com { return thread[tid].getLoadHead(); } 1578303SAli.Saidi@ARM.com 1588303SAli.Saidi@ARM.com /** Returns the sequence number of the head of the load queue. */ 1598303SAli.Saidi@ARM.com InstSeqNum getLoadHeadSeqNum(unsigned tid) 1608303SAli.Saidi@ARM.com { 1618303SAli.Saidi@ARM.com return thread[tid].getLoadHeadSeqNum(); 1628303SAli.Saidi@ARM.com } 1638303SAli.Saidi@ARM.com 1648304SAli.Saidi@ARM.com /** Returns the head index of the store queue. */ 1658303SAli.Saidi@ARM.com int getStoreHead(unsigned tid) 1668304SAli.Saidi@ARM.com { return thread[tid].getStoreHead(); } 1678304SAli.Saidi@ARM.com 1688303SAli.Saidi@ARM.com /** Returns the sequence number of the head of the store queue. */ 1698303SAli.Saidi@ARM.com InstSeqNum getStoreHeadSeqNum(unsigned tid) 1708303SAli.Saidi@ARM.com { 1718303SAli.Saidi@ARM.com return thread[tid].getStoreHeadSeqNum(); 1728303SAli.Saidi@ARM.com } 1738303SAli.Saidi@ARM.com 1748303SAli.Saidi@ARM.com /** Returns the number of instructions in all of the queues. */ 1758304SAli.Saidi@ARM.com int getCount(); 1768303SAli.Saidi@ARM.com /** Returns the number of instructions in the queues of one thread. */ 1777422Sgblack@eecs.umich.edu int getCount(unsigned tid) 1787119Sgblack@eecs.umich.edu { return thread[tid].getCount(); } 1797119Sgblack@eecs.umich.edu 1807119Sgblack@eecs.umich.edu /** Returns the total number of loads in the load queue. */ 1817119Sgblack@eecs.umich.edu int numLoads(); 1827590Sgblack@eecs.umich.edu /** Returns the total number of loads for a single thread. */ 1837590Sgblack@eecs.umich.edu int numLoads(unsigned tid) 1847119Sgblack@eecs.umich.edu { return thread[tid].numLoads(); } 1857590Sgblack@eecs.umich.edu 1867590Sgblack@eecs.umich.edu /** Returns the total number of stores in the store queue. */ 1877590Sgblack@eecs.umich.edu int numStores(); 1887590Sgblack@eecs.umich.edu /** Returns the total number of stores for a single thread. */ 1897590Sgblack@eecs.umich.edu int numStores(unsigned tid) 1907119Sgblack@eecs.umich.edu { return thread[tid].numStores(); } 1917119Sgblack@eecs.umich.edu 1927119Sgblack@eecs.umich.edu /** Returns the total number of loads that are ready. */ 1937119Sgblack@eecs.umich.edu int numLoadsReady(); 1947119Sgblack@eecs.umich.edu /** Returns the number of loads that are ready for a single thread. */ 1957119Sgblack@eecs.umich.edu int numLoadsReady(unsigned tid) 19610346Smitch.hayenga@arm.com { return thread[tid].numLoadsReady(); } 19710346Smitch.hayenga@arm.com 19810346Smitch.hayenga@arm.com /** Returns the number of free entries. */ 19910037SARM gem5 Developers unsigned numFreeEntries(); 20010037SARM gem5 Developers /** Returns the number of free entries for a specific thread. */ 20110037SARM gem5 Developers unsigned numFreeEntries(unsigned tid); 20210037SARM gem5 Developers 20310037SARM gem5 Developers /** Returns if the LSQ is full (either LQ or SQ is full). */ 20410037SARM gem5 Developers bool isFull(); 2057119Sgblack@eecs.umich.edu /** 2067119Sgblack@eecs.umich.edu * Returns if the LSQ is full for a specific thread (either LQ or SQ is 2078588Sgblack@eecs.umich.edu * full). 2087119Sgblack@eecs.umich.edu */ 2098588Sgblack@eecs.umich.edu bool isFull(unsigned tid); 2107119Sgblack@eecs.umich.edu 2117119Sgblack@eecs.umich.edu /** Returns if any of the LQs are full. */ 2128588Sgblack@eecs.umich.edu bool lqFull(); 2137119Sgblack@eecs.umich.edu /** Returns if the LQ of a given thread is full. */ 2148588Sgblack@eecs.umich.edu bool lqFull(unsigned tid); 2157119Sgblack@eecs.umich.edu 2167590Sgblack@eecs.umich.edu /** Returns if any of the SQs are full. */ 2177119Sgblack@eecs.umich.edu bool sqFull(); 2187119Sgblack@eecs.umich.edu /** Returns if the SQ of a given thread is full. */ 2197119Sgblack@eecs.umich.edu bool sqFull(unsigned tid); 2207119Sgblack@eecs.umich.edu 2217119Sgblack@eecs.umich.edu /** 2227132Sgblack@eecs.umich.edu * Returns if the LSQ is stalled due to a memory operation that must be 2237119Sgblack@eecs.umich.edu * replayed. 2247132Sgblack@eecs.umich.edu */ 2257119Sgblack@eecs.umich.edu bool isStalled(); 2267132Sgblack@eecs.umich.edu /** 2277119Sgblack@eecs.umich.edu * Returns if the LSQ of a specific thread is stalled due to a memory 2287119Sgblack@eecs.umich.edu * operation that must be replayed. 2297119Sgblack@eecs.umich.edu */ 2307119Sgblack@eecs.umich.edu bool isStalled(unsigned tid); 2317119Sgblack@eecs.umich.edu 232 /** Returns whether or not there are any stores to write back to memory. */ 233 bool hasStoresToWB(); 234 235 /** Returns whether or not a specific thread has any stores to write back 236 * to memory. 237 */ 238 bool hasStoresToWB(unsigned tid) 239 { return thread[tid].hasStoresToWB(); } 240 241 /** Returns the number of stores a specific thread has to write back. */ 242 int numStoresToWB(unsigned tid) 243 { return thread[tid].numStoresToWB(); } 244 245 /** Returns if the LSQ will write back to memory this cycle. */ 246 bool willWB(); 247 /** Returns if the LSQ of a specific thread will write back to memory this 248 * cycle. 249 */ 250 bool willWB(unsigned tid) 251 { return thread[tid].willWB(); } 252 253 /** Debugging function to print out all instructions. */ 254 void dumpInsts(); 255 /** Debugging function to print out instructions from a specific thread. */ 256 void dumpInsts(unsigned tid) 257 { thread[tid].dumpInsts(); } 258 259 /** Executes a read operation, using the load specified at the load index. */ 260 template <class T> 261 Fault read(MemReqPtr &req, T &data, int load_idx); 262 263 /** Executes a store operation, using the store specified at the store 264 * index. 265 */ 266 template <class T> 267 Fault write(MemReqPtr &req, T &data, int store_idx); 268 269 private: 270 /** The LSQ policy for SMT mode. */ 271 LSQPolicy lsqPolicy; 272 273 /** The LSQ units for individual threads. */ 274 LSQUnit thread[Impl::MaxThreads]; 275 276 /** The CPU pointer. */ 277 FullCPU *cpu; 278 279 /** The IEW stage pointer. */ 280 IEW *iewStage; 281 282 /** The pointer to the page table. */ 283// PageTable *pTable; 284 285 /** List of Active Threads in System. */ 286 std::list<unsigned> *activeThreads; 287 288 /** Total Size of LQ Entries. */ 289 unsigned LQEntries; 290 /** Total Size of SQ Entries. */ 291 unsigned SQEntries; 292 293 /** Max LQ Size - Used to Enforce Sharing Policies. */ 294 unsigned maxLQEntries; 295 296 /** Max SQ Size - Used to Enforce Sharing Policies. */ 297 unsigned maxSQEntries; 298 299 /** Number of Threads. */ 300 unsigned numThreads; 301}; 302 303template <class Impl> 304template <class T> 305Fault 306LSQ<Impl>::read(MemReqPtr &req, T &data, int load_idx) 307{ 308 unsigned tid = req->thread_num; 309 310 return thread[tid].read(req, data, load_idx); 311} 312 313template <class Impl> 314template <class T> 315Fault 316LSQ<Impl>::write(MemReqPtr &req, T &data, int store_idx) 317{ 318 unsigned tid = req->thread_num; 319 320 return thread[tid].write(req, data, store_idx); 321} 322 323#endif // __CPU_O3_LSQ_HH__ 324