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