/*
 * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __MEM_RUBY_STRUCTURES_PREFETCHER_HH__
#define __MEM_RUBY_STRUCTURES_PREFETCHER_HH__

// Implements Power 4 like prefetching

#include <bitset>

#include "base/statistics.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/network/MessageBuffer.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh"
#include "mem/ruby/slicc_interface/RubyRequest.hh"
#include "mem/ruby/system/RubySystem.hh"
#include "params/Prefetcher.hh"
#include "sim/sim_object.hh"
#include "sim/system.hh"

#define MAX_PF_INFLIGHT 8

class PrefetchEntry
{
    public:
        /// constructor
        PrefetchEntry()
        {
            // default: 1 cache-line stride
            m_stride   = (1 << RubySystem::getBlockSizeBits());
            m_use_time = Cycles(0);
            m_is_valid = false;
        }

        //! The base address for the stream prefetch
        Addr m_address;

        //! stride distance to get next address from
        int m_stride;

        //! the last time that any prefetched request was used
        Cycles m_use_time;

        //! valid bit for each stream
        bool m_is_valid;

        //! L1D prefetches loads and stores
        RubyRequestType m_type;

        //! Bitset for tracking prefetches for which addresses have been
        //! issued, which ones have completed.
        std::bitset<MAX_PF_INFLIGHT> requestIssued;
        std::bitset<MAX_PF_INFLIGHT> requestCompleted;
};

class Prefetcher : public SimObject
{
    public:
        typedef PrefetcherParams Params;
        Prefetcher(const Params *p);
        ~Prefetcher();

        void issueNextPrefetch(Addr address, PrefetchEntry *stream);
        /**
         * Implement the prefetch hit(miss) callback interface.
         * These functions are called by the cache when it hits(misses)
         * on a line with the line's prefetch bit set. If this address
         * hits in m_array we will continue prefetching the stream.
         */
        void observePfHit(Addr address);
        void observePfMiss(Addr address);

        /**
         * Observe a memory miss from the cache.
         *
         * @param address   The physical address that missed out of the cache.
         */
        void observeMiss(Addr address, const RubyRequestType& type);

        /**
         * Print out some statistics
         */
        void print(std::ostream& out) const;
        void setController(AbstractController *_ctrl)
        { m_controller = _ctrl; }

        void regStats();

    private:
        /**
         * Returns an unused stream buffer (or if all are used, returns the
         * least recently used (accessed) stream buffer).
         * @return  The index of the least recently used stream buffer.
         */
        uint32_t getLRUindex(void);

        //! clear a non-unit stride prefetcher entry
        void clearNonunitEntry(uint32_t index);

        //! allocate a new stream buffer at a specific index
        void initializeStream(Addr address, int stride,
            uint32_t index, const RubyRequestType& type);

        //! get pointer to the matching stream entry, returns NULL if not found
        //! index holds the multiple of the stride this address is.
        PrefetchEntry* getPrefetchEntry(Addr address,
            uint32_t &index);

        /// access a unit stride filter to determine if there is a hit
        bool accessUnitFilter(std::vector<Addr>& filter_table,
            uint32_t *hit_table, uint32_t &index, Addr address,
            int stride, bool &alloc);

        /// access a unit stride filter to determine if there is a hit
        bool accessNonunitFilter(Addr address, int *stride,
            bool &alloc);

        /// determine the page aligned address
        Addr pageAddress(Addr addr) const;

        //! number of prefetch streams available
        uint32_t m_num_streams;
        //! an array of the active prefetch streams
        std::vector<PrefetchEntry> m_array;

        //! number of misses I must see before allocating a stream
        uint32_t m_train_misses;
        //! number of initial prefetches to startup a stream
        uint32_t m_num_startup_pfs;
        //! number of stride filters
        uint32_t m_num_unit_filters;
        //! number of non-stride filters
        uint32_t m_num_nonunit_filters;

        /// a unit stride filter array: helps reduce BW requirement of
        /// prefetching
        std::vector<Addr> m_unit_filter;
        /// a round robin pointer into the unit filter group
        uint32_t m_unit_filter_index;
        //! An array used to count the of times particular filter entries
        //! have been hit
        uint32_t *m_unit_filter_hit;

        //! a negative nit stride filter array: helps reduce BW requirement
        //! of prefetching
        std::vector<Addr> m_negative_filter;
        /// a round robin pointer into the negative filter group
        uint32_t m_negative_filter_index;
        /// An array used to count the of times particular filter entries
        /// have been hit
        uint32_t *m_negative_filter_hit;

        /// a non-unit stride filter array: helps reduce BW requirement of
        /// prefetching
        std::vector<Addr> m_nonunit_filter;
        /// An array of strides (in # of cache lines) for the filter entries
        int *m_nonunit_stride;
        /// An array used to count the of times particular filter entries
        /// have been hit
        uint32_t *m_nonunit_hit;
        /// a round robin pointer into the unit filter group
        uint32_t m_nonunit_index;

        /// Used for allowing prefetches across pages.
        bool m_prefetch_cross_pages;

        AbstractController *m_controller;

        const Addr m_page_shift;

        //! Count of accesses to the prefetcher
        Stats::Scalar numMissObserved;
        //! Count of prefetch streams allocated
        Stats::Scalar numAllocatedStreams;
        //! Count of prefetch requests made
        Stats::Scalar numPrefetchRequested;
        //! Count of prefetch requests accepted
        Stats::Scalar numPrefetchAccepted;
        //! Count of prefetches dropped
        Stats::Scalar numDroppedPrefetches;
        //! Count of successful prefetches
        Stats::Scalar numHits;
        //! Count of partial successful prefetches
        Stats::Scalar numPartialHits;
        //! Count of pages crossed
        Stats::Scalar numPagesCrossed;
        //! Count of misses incurred for blocks that were prefetched
        Stats::Scalar numMissedPrefetchedBlocks;
};

#endif // __MEM_RUBY_STRUCTURES_PREFETCHER_HH__
