/*
 * Copyright (c) 2015, University of Kaiserslautern
 * All rights reserved.
 *
 * 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:
 *    Janik Schlemminger
 *    Matthias Jung
 */

#ifndef MemSpec_H_
#define MemSpec_H_

#include <systemc.h>
#include <map>
#include "../../../common/dramExtension.h"


struct RefreshTiming {
    RefreshTiming() {}
    RefreshTiming(sc_time tRFC, sc_time tREFI) : tRFC(tRFC), tRFC2(SC_ZERO_TIME),
        tRFC4(SC_ZERO_TIME), tREFI(tREFI) {}
    RefreshTiming(sc_time tRFC, sc_time tRFC2, sc_time tRFC4,
                  sc_time tREFI) : tRFC(tRFC), tRFC2(tRFC2), tRFC4(tRFC4), tREFI(tREFI) {}
    sc_time tRFC;
    sc_time tRFC2;
    sc_time tRFC4;
    sc_time tREFI;
};

struct MemSpec {
    MemSpec()
    {
        //default DDR4
    }

    const std::vector<Bank> &getBanks() const
    {
        static std::vector<Bank> banks;
        if (banks.size() == 0) {
            for (unsigned int i = 0; i < NumberOfBanks; i++) {
                banks.push_back(Bank(i));
            }
        }

        return banks;
    }

    std::string MemoryId = "not defined.";
    std::string MemoryType = "not defined.";

    unsigned int NumberOfBanks;
    unsigned int NumberOfBankGroups;
    unsigned int NumberOfRanks;
    unsigned int BurstLength;
    unsigned int nActivate;
    unsigned int DataRate;
    unsigned int NumberOfRows;
    unsigned int NumberOfColumns;
    unsigned int bitWidth;
    bool DLL;
    bool termination;

    // Memspec Variables:
    double clkMHz;
    sc_time clk;
    sc_time tRP;        //precharge-time (pre -> act same bank)
    sc_time tRPAB;      //precharge-all time only for LPDDR4
    sc_time tRAS;       //active-time (act -> pre same bank)
    sc_time tRC;        //RAS-cycle-time (min time bw 2 succesive ACT to same bank)
    sc_time tCCD_S;     //max(bl, tCCD) is relevant for rd->rd
    sc_time tCCD_L;
    sc_time tRTP;       //Read to precharge
    sc_time tRRD_S;     //min time bw 2 succesive ACT to different banks (different bank group)
    sc_time tRRD_L;     //.. (same bank group)
    sc_time tRCD;       //act -> read/write
    sc_time tNAW;       //n activate window
    sc_time tRL;        //read latency (read command start to data strobe)
    sc_time tWL;        //write latency
    sc_time tWR;        //write recovery (write to precharge)
    sc_time tWTR_S;     //write to read (different bank group)
    sc_time tWTR_L;     //.. (same bank group)
    sc_time tCKESR;     //min time in sref
    sc_time tCKE;       //min time in pdna or pdnp
    sc_time tXP;        //min delay to row access command after pdnpx pdnax
    sc_time tXPDLL;     //min delay to row access command after pdnpx pdnax for dll commands
    sc_time tXSR;       //min delay to row access command after srefx
    sc_time tXSRDLL;    //min delay to row access command after srefx for dll commands
    sc_time tAL;        //additive delay (delayed execution in dram)
    sc_time tDQSCK;

    sc_time tRFC;       //min ref->act delay 1X mode
    sc_time tRFC2;      //min ref->act delay 2X mode
    sc_time tRFC4;      //min ref->act delay 4X mode
    sc_time tREFI;      //auto refresh must be issued at an average periodic interval tREFI

    // Currents and Voltages:
    double iDD0;
    double iDD02;
    double iDD2P0;
    double iDD2P02;
    double iDD2P1;
    double iDD2P12;
    double iDD2N;
    double iDD2N2;
    double iDD3P0;
    double iDD3P02;
    double iDD3P1;
    double iDD3P12;
    double iDD3N;
    double iDD3N2;
    double iDD4R;
    double iDD4R2;
    double iDD4W;
    double iDD4W2;
    double iDD5;
    double iDD52;
    double iDD6;
    double iDD62;
    double vDD;
    double vDD2;


    std::map<Bank, RefreshTiming>
    refreshTimings;//ensure that map is populated completely in memspecloader

    //act and read/write commands remain for this timespan in history
    sc_time tActHistory()
    {
        return tNAW;
    }
    sc_time tActBHistory()
    {
        return tNAW;
    }
    sc_time tDataStrobeHistory()
    {
        return tWTR_L;
    }
};

#endif /* MemSpec_H_ */

