/*
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * For use for simulation and test purposes only
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the copyright holder 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 HOLDER 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.
 *
 * Authors: Tuan Ta
 */

#ifndef CPU_TESTERS_PROTOCOL_TESTER_ADDRESSMANAGER_HH_
#define CPU_TESTERS_PROTOCOL_TESTER_ADDRESSMANAGER_HH_

#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#include "base/types.hh"
#include "sim/eventq.hh"

/*
 * --- AddressManager has 3 main tasks ---
 *    (1) generate DRF request sequences
 *    (2) maintain internal log table
 *    (3) validate return values against ones in the log table
 *
 * A location is an abstract index of a unique real address.
 *    It's used internally within the tester only.
 *    randAddressMap has the mapping between a location and its real address.
 *
 * A value is an integer that a location in real memory can store.
 *    for now, we assume a value is 4-byte
 *
 * The location range (randAddressMap) has two distinct parts:
 *    Atomic locations: in the 1st part of randAddressMap &
 *    Non-atomic locations (or just locations): in the 2nd part
 */

/*
 * --- DRF request sequence generation ---
 *    Each lane of an episode starts selecting its location by calling:
 *      (1) getAtomicLoc
 *      (2) getLoadLoc/getStoreLoc
 *      (3) finishLocSelection
 *
 *    Each lane of an episode completes its executing by calling:
 *      releaseLocation for all locations it selected
 */

/*
 * --- Internal structures ---
 *  There are multiple atomic structures, each of which corresponds
 *    to an atomic location.
 *
 *  Each atomic structure manages a distinct range of locations in locArray
 *  This array is partitioned into 3 parts that are used to select locations
 *  for LDs and STs. Here is the location selecting rule:
 *                  |    (1)    |    (2)    |    (3)    |
 *    - all locations in (1) cannot be picked for any LD and ST action
 *    - all locations in (2) can be picked for either LD or ST action
 *    - all locations in (3) can be picked for LD action only
 *
 *  We maintain the 3 parts by 2 indices firstMark and secondMark.
 *  As locations are moved between partitions, both indices are updated
 *  accordingly.
 *    [0 .. firstMark-1]                  part (1)
 *    [firstMark .. secondMark-1]      part (2)
 *    [secondMark .. arraySize-1]        part (3)
 *
 *  Each location has its context/property. locProps maintains
 *  contexts/properties of all locations. Context/property includes
 *      - current index of a location in locArray
 *      - the number of owners who are currently using the location
 *
 *  To guarantee DRF constraints, the following conditions must hold
 *    - all locations in (1) have exactly 1 owner
 *    - all locations in (2) have exactly 0 owner
 *    - all locations in (3) have at least 1 owner
 *    - A LD request can randomly pick any location in (2) & (3)
 *    - A ST request can randomly pick any location in (2)
 *
 *  loadStoreMap maintains all locations already selected for LDs/STs so far
 *
 *  When endLocSelection is called (i.e., we've picked all locations for an
 *  episode), we need to move each selected location to its right partition.
 *    if LD_bit == 1 && ST_bit == 0 (i.e., picked for LDs), then move the
 *          location to (3) -> future LDs can pick it.
 *    if LD_bit == 0 && ST_bit == 1, then move the location to (1) -> NO future
 *          action can pick it until this episode is done.
 *    if LD_bit == 1 && ST_bit == 1, then move the location to (1) -> NO future
 *          action can pick it until this episode is done.
 *    clear the loadStoreMap
 */

class AddressManager
{
  public:
    AddressManager(int n_atomic_locs, int numNormalLocsPerAtomic);
    ~AddressManager();

    typedef int32_t Value;
    typedef int32_t Location;

    // return the unique address mapped to a location
    Addr getAddress(Location loc);
    // return a unique atomic location & start picking locations
    Location getAtomicLoc();
    // return a random location for LD
    Location getLoadLoc(Location atomic_loc);
    // return a random location for ST
    Location getStoreLoc(Location atomic_loc);
    // finish picking locations
    void finishLocSelection(Location atomic_loc);
    // an episode is done, release location I've picked
    void releaseLocation(Location atomic_loc, Location loc);
    // update a log table entry with a given set of values
    void updateLogTable(Location loc, int threadId, int episodeId,
                        Value new_value, Tick curTick, int cuId = -1);
    // return the current value in the log table
    Value getLoggedValue(Location loc) const;
    // validate atomic response
    bool validateAtomicResp(Location loc, Value ret_val);

    std::string printLastWriter(Location loc) const;

    static const int INVALID_VALUE;
    static const int INVALID_LOCATION;

  private:
    class LastWriter
    {
      public:
        LastWriter()
            : threadId(-1), cuId(-1), episodeId(-1), value(0),
              writeTick(0)
        { }

        const std::string print() const
        {
            return "(Thread ID " + std::to_string(threadId) +
                   ", CU ID " + std::to_string(cuId) +
                   ", Episode ID " + std::to_string(episodeId) +
                   ", Value " + std::to_string(value) +
                   ", Tick " + std::to_string(writeTick) +
                   ")";
        }

        void update(int _thread, int _cu, int _episode, Value _value,
                    Tick _tick)
        {
            threadId = _thread;
            cuId = _cu;
            episodeId = _episode;
            value = _value;
            writeTick = _tick;
        }

        Value getLastStoredValue() const { return value; }

      private:
        int threadId;
        int cuId;
        int episodeId;
        Value value;
        Tick writeTick;
    };

    class AtomicStruct
    {
      public:
        AtomicStruct(Location atom_loc, Location loc_begin, Location loc_end);
        ~AtomicStruct();

        // functions picking locations for LD/ST/ATOMIC ops
        void startLocSelection();
        Location getLoadLoc();
        Location getStoreLoc();
        void endLocSelection();

        // an episode completed its actions
        // return locations to their correct positions
        void releaseLoc(Location loc);
        // is the value what we expect?
        bool isExpectedValue(Value val);

      private:
        Location atomicLoc;
        Location locationBase;

        // array storing all locations this structure is managing
        Location* locArray;
        int firstMark, secondMark;
        int arraySize;

        // a vector of location's properties
        typedef std::pair<int, int> LocProperty;
        typedef std::vector<LocProperty> LocPropTable;
        LocPropTable locProps;

        // a temporary map of location and its LD/ST selection
        typedef std::pair<bool, bool> LdStBits;
        typedef std::unordered_map<Location, LdStBits> LdStMap;
        LdStMap loadStoreMap;

        // number of atomic requests at this location so far
        int requestCount;
        // a set of expected values
        // when we request the first n atomic ops, we expect to receive n
        // return values from [0 .. n-1]
        typedef std::unordered_set<Value> ExpectedValueSet;
        ExpectedValueSet expectedValues;

        // swap two locations in locArray
        void swap(LocProperty& prop_1, LocProperty& prop_2);

        bool inFirstRegion(int idx) const
        {
            return (idx >= 0 && idx < firstMark);
        }
        bool inSecondRegion(int idx) const
        {
            return (idx >= firstMark && idx < secondMark);
        }
        bool inThirdRegion(int idx) const
        {
            return (idx >= secondMark && idx < arraySize);
        }
    };

    // number of atomic locations
    int numAtomicLocs;
    // number of normal/non-atomic locations per atomic structure
    int numLocsPerAtomic;
    // total number of non-atomic locations
    int numNormalLocs;

    // location - address mapping
    typedef std::vector<Addr> AddressMap;
    AddressMap randAddressMap;

    // a list of atomic structures
    typedef std::vector<AtomicStruct*> AtomicStructTable;
    AtomicStructTable atomicStructs;

    // internal log table
    typedef std::vector<LastWriter*> LogTable;
    LogTable logTable;
};

#endif /* CPU_TESTERS_PROTOCOL_TESTER_ADDRESSMANAGER_HH_ */
