/*
 * Copyright (c) 2004-2005 The Regents of The University of Michigan
 * 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.
 */

/**
 * @file
 * Definition of a memory trace CPU object for optimal caches. Uses a memory
 * trace to access a fully associative cache with optimal replacement.
 */

#include <algorithm> // For heap functions.

#include "cpu/trace/opt_cpu.hh"
#include "cpu/trace/reader/mem_trace_reader.hh"

#include "sim/builder.hh"
#include "sim/sim_events.hh"

using namespace std;

OptCPU::OptCPU(const string &name,
               MemTraceReader *_trace,
               int block_size,
               int cache_size,
               int _assoc)
    : SimObject(name), tickEvent(this), trace(_trace),
      numBlks(cache_size/block_size), assoc(_assoc), numSets(numBlks/assoc),
      setMask(numSets - 1)
{
    int log_block_size = 0;
    int tmp_block_size = block_size;
    while (tmp_block_size > 1) {
        ++log_block_size;
        tmp_block_size = tmp_block_size >> 1;
    }
    assert(1<<log_block_size == block_size);
    MemReqPtr req;
    trace->getNextReq(req);
    refInfo.resize(numSets);
    while (req) {
        RefInfo temp;
        temp.addr = req->paddr >> log_block_size;
        int set = temp.addr & setMask;
        refInfo[set].push_back(temp);
        trace->getNextReq(req);
    }

    // Initialize top level of lookup table.
    lookupTable.resize(16);

    // Annotate references with next ref time.
    for (int k = 0; k < numSets; ++k) {
        for (RefIndex i = refInfo[k].size() - 1; i >= 0; --i) {
            Addr addr = refInfo[k][i].addr;
            initTable(addr, InfiniteRef);
            refInfo[k][i].nextRefTime = lookupValue(addr);
            setValue(addr, i);
        }
    }

    // Reset the lookup table
    for (int j = 0; j < 16; ++j) {
        if (lookupTable[j].size() == (1<<16)) {
            for (int k = 0; k < (1<<16); ++k) {
                if (lookupTable[j][k].size() == (1<<16)) {
                    for (int l = 0; l < (1<<16); ++l) {
                        lookupTable[j][k][l] = -1;
                    }
                }
            }
        }
    }

    tickEvent.schedule(0);

    hits = 0;
    misses = 0;
}

void
OptCPU::processSet(int set)
{
    // Initialize cache
    int blks_in_cache = 0;
    RefIndex i = 0;
    cacheHeap.clear();
    cacheHeap.resize(assoc);

    while (blks_in_cache < assoc) {
        RefIndex cache_index = lookupValue(refInfo[set][i].addr);
        if (cache_index == -1) {
            // First reference to this block
            misses++;
            cache_index = blks_in_cache++;
            setValue(refInfo[set][i].addr, cache_index);
        } else {
            hits++;
        }
        // update cache heap to most recent reference
        cacheHeap[cache_index] = i;
        if (++i >= refInfo[set].size()) {
            return;
        }
    }
    for (int start = assoc/2; start >= 0; --start) {
        heapify(set,start);
    }
    //verifyHeap(set,0);

    for (; i < refInfo[set].size(); ++i) {
        RefIndex cache_index = lookupValue(refInfo[set][i].addr);
        if (cache_index == -1) {
            // miss
            misses++;
            // replace from cacheHeap[0]
            // mark replaced block as absent
            setValue(refInfo[set][cacheHeap[0]].addr, -1);
            setValue(refInfo[set][i].addr, 0);
            cacheHeap[0] = i;
            heapify(set, 0);
            // Make sure its in the cache
            assert(lookupValue(refInfo[set][i].addr) != -1);
        } else {
            // hit
            hits++;
            assert(refInfo[set][cacheHeap[cache_index]].addr ==
                   refInfo[set][i].addr);
            assert(refInfo[set][cacheHeap[cache_index]].nextRefTime == i);
            assert(heapLeft(cache_index) >= assoc);

            cacheHeap[cache_index] = i;
            processRankIncrease(set, cache_index);
            assert(lookupValue(refInfo[set][i].addr) != -1);
        }
    }
}
void
OptCPU::tick()
{
    // Do opt simulation

    int references = 0;
    for (int set = 0; set < numSets; ++set) {
        if (!refInfo[set].empty()) {
            processSet(set);
        }
        references += refInfo[set].size();
    }
    // exit;
    fprintf(stderr,"sys.cpu.misses %d #opt cache misses\n",misses);
    fprintf(stderr,"sys.cpu.hits %d #opt cache hits\n", hits);
    fprintf(stderr,"sys.cpu.accesses %d #opt cache acceses\n", references);
    new SimExitEvent("Finshed Memory Trace");
}

void
OptCPU::initTable(Addr addr, RefIndex index)
{
    int l1_index = (addr >> 32) & 0x0f;
    int l2_index = (addr >> 16) & 0xffff;
    assert(l1_index == addr >> 32);
    if (lookupTable[l1_index].size() != (1<<16)) {
        lookupTable[l1_index].resize(1<<16);
    }
    if (lookupTable[l1_index][l2_index].size() != (1<<16)) {
        lookupTable[l1_index][l2_index].resize(1<<16, index);
    }
}

OptCPU::TickEvent::TickEvent(OptCPU *c)
    : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c)
{
}

void
OptCPU::TickEvent::process()
{
    cpu->tick();
}

const char *
OptCPU::TickEvent::description()
{
    return "OptCPU tick event";
}


BEGIN_DECLARE_SIM_OBJECT_PARAMS(OptCPU)

    SimObjectParam<MemTraceReader *> data_trace;
    Param<int> size;
    Param<int> block_size;
Param<int> assoc;

END_DECLARE_SIM_OBJECT_PARAMS(OptCPU)

BEGIN_INIT_SIM_OBJECT_PARAMS(OptCPU)

    INIT_PARAM_DFLT(data_trace, "memory trace", NULL),
    INIT_PARAM(size, "cache size"),
    INIT_PARAM(block_size, "block size"),
    INIT_PARAM(assoc,"associativity")

END_INIT_SIM_OBJECT_PARAMS(OptCPU)

CREATE_SIM_OBJECT(OptCPU)
{
    return new OptCPU(getInstanceName(),
                      data_trace,
                      block_size,
                      size,
                      assoc);
}

REGISTER_SIM_OBJECT("OptCPU", OptCPU)
