/*
 * Copyright (c) 2018-2020 Inria
 * 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 basic cache compressor.
 * A cache compressor must consist of a compression and a decompression
 * methods. It must also be aware of the size of an uncompressed cache
 * line.
 */

#ifndef __MEM_CACHE_COMPRESSORS_BASE_HH__
#define __MEM_CACHE_COMPRESSORS_BASE_HH__

#include <cstdint>

#include "base/statistics.hh"
#include "base/types.hh"
#include "sim/sim_object.hh"

class CacheBlk;
struct BaseCacheCompressorParams;

namespace Compressor {

/**
 * Base cache compressor interface. Every cache compressor must implement a
 * compression and a decompression method.
 *
 * Compressors usually cannot parse all data input at once. Therefore, they
 * typically divide the input into multiple *chunks*, and parse them one at
 * a cycle.
 */
class Base : public SimObject
{
  public:
    /**
     * Forward declaration of compression data. Every new compressor must
     * create a new compression data based on it.
     */
    class CompressionData;

  protected:
    /**
     * A chunk is a basic lexical unit. The data being compressed is received
     * by the compressor as a raw pointer. In order to parse this data, the
     * compressor must divide it into smaller units. Typically, state-of-the-
     * art compressors interpret cache lines as sequential 32-bit chunks
     * (chunks), but any size is valid.
     * @sa chunkSizeBits
     */
    typedef uint64_t Chunk;

    /**
     * This compressor must be able to access the protected functions of
     * its sub-compressors.
     */
    friend class Multi;

    /**
     * Uncompressed cache line size (in bytes).
     */
    const std::size_t blkSize;

    /** Chunk size, in number of bits. */
    const unsigned chunkSizeBits;

    /**
     * Size in bytes at which a compression is classified as bad and therefore
     * the compressed block is restored to its uncompressed format.
     */
    const std::size_t sizeThreshold;

    struct BaseStats : public Stats::Group
    {
        const Base& compressor;

        BaseStats(Base& compressor);

        void regStats() override;

        /** Number of compressions performed. */
        Stats::Scalar compressions;

        /** Number of failed compressions. */
        Stats::Scalar failedCompressions;

        /** Number of blocks that were compressed to this power of two size. */
        Stats::Vector compressionSize;

        /** Total compressed data size, in number of bits. */
        Stats::Scalar compressionSizeBits;

        /** Average data size after compression, in number of bits. */
        Stats::Formula avgCompressionSizeBits;

        /** Number of decompressions performed. */
        Stats::Scalar decompressions;
    } stats;

    /**
     * This function splits the raw data into chunks, so that it can be
     * parsed by the compressor.
     *
     * @param data The raw pointer to the data being compressed.
     * @return The raw data divided into a vector of sequential chunks.
     */
    std::vector<Chunk> toChunks(const uint64_t* data) const;

    /**
     * This function re-joins the chunks to recreate the original data.
     *
     * @param chunks The raw data divided into a vector of sequential chunks.
     * @param data The raw pointer to the data.
     */
    void fromChunks(const std::vector<Chunk>& chunks, uint64_t* data) const;

    /**
     * Apply the compression process to the cache line.
     * Returns the number of cycles used by the compressor, however it is
     * usually covered by a good pipelined execution, and is currently ignored.
     * The decompression latency is also returned, in order to avoid
     * increasing simulation time and memory consumption.
     *
     * @param chunks The cache line to be compressed, divided into chunks.
     * @param comp_lat Compression latency in number of cycles.
     * @param decomp_lat Decompression latency in number of cycles.
     * @return Cache line after compression.
     */
    virtual std::unique_ptr<CompressionData> compress(
        const std::vector<Chunk>& chunks, Cycles& comp_lat,
        Cycles& decomp_lat) = 0;

    /**
     * Apply the decompression process to the compressed data.
     *
     * @param comp_data Compressed cache line.
     * @param cache_line The cache line to be decompressed.
     */
    virtual void decompress(const CompressionData* comp_data,
                              uint64_t* cache_line) = 0;

  public:
    typedef BaseCacheCompressorParams Params;
    Base(const Params *p);
    virtual ~Base() = default;

    /**
     * Apply the compression process to the cache line. Ignores compression
     * cycles.
     *
     * @param data The cache line to be compressed.
     * @param comp_lat Compression latency in number of cycles.
     * @param decomp_lat Decompression latency in number of cycles.
     * @return Cache line after compression.
     */
    std::unique_ptr<CompressionData>
    compress(const uint64_t* data, Cycles& comp_lat, Cycles& decomp_lat);

    /**
     * Get the decompression latency if the block is compressed. Latency is 0
     * otherwise.
     *
     * @param blk The compressed block.
     */
    Cycles getDecompressionLatency(const CacheBlk* blk);

    /**
     * Set the decompression latency of compressed block.
     *
     * @param blk The compressed block.
     * @param lat The decompression latency.
     */
    static void setDecompressionLatency(CacheBlk* blk, const Cycles lat);

    /**
     * Set the size of the compressed block, in bits.
     *
     * @param blk The compressed block.
     * @param size_bits The block size.
     */
    static void setSizeBits(CacheBlk* blk, const std::size_t size_bits);
};

class Base::CompressionData
{
  private:
    /**
     * Compressed cache line size (in bits).
     */
    std::size_t _size;

  public:
    /**
     * Default constructor.
     */
    CompressionData();

    /**
     * Virtual destructor. Without it unique_ptr will cause mem leak.
     */
    virtual ~CompressionData();

    /**
     * Set compression size (in bits).
     *
     * @param size Compressed data size.
     */
    void setSizeBits(std::size_t size);

    /**
     * Get compression size (in bits).
     *
     * @return Compressed data size.
     */
    std::size_t getSizeBits() const;

    /**
     * Get compression size (in bytes).
     *
     * @return Compressed data size.
     */
    std::size_t getSize() const;
};

} // namespace Compressor

#endif //__MEM_CACHE_COMPRESSORS_BASE_HH__
