/* -*- c++ -*-
 *
 * SOCLIB_LGPL_HEADER_BEGIN
 * 
 * This file is part of SoCLib, GNU LGPLv2.1.
 * 
 * SoCLib is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; version 2.1 of the License.
 * 
 * SoCLib is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with SoCLib; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA
 * 
 * SOCLIB_LGPL_HEADER_END
 *
 * Copyright (c) UPMC, Lip6
 *         Ghassan Almaless <ghassan.almaless@lip6.fr>, 2011
 *
 * Maintainers: Ghassan
 */
#ifndef SOCLIB_CABA_VCI_PROFILER_H
#define SOCLIB_CABA_VCI_PROFILER_H

#include <systemc>
#include <iostream>
#include <fstream>
#include "vci_monitor.h"
#include "vci_buffers.h"
#include "caba_base_module.h"
#include "mapping_table.h"
//#include "config.h"
#include "vci_cc_vcache_wrapper2_v1.h"

namespace soclib {
namespace caba {

template<typename vci_param, typename iss_t>
class VciProfiler
	: public soclib::caba::BaseModule
{

protected:
	SC_HAS_PROCESS(VciProfiler);

public:
    sc_core::sc_in<bool> p_resetn;
    sc_core::sc_in<bool> p_clk;
    soclib::caba::VciMonitor<vci_param> p_vci;

    VciProfiler(
              sc_core::sc_module_name insname,
              size_t index, 
              size_t x_id,
              size_t y_id,
              size_t x_width,
              size_t y_width,
              size_t addr_width);

    void print_stats(void);
    void clear_stats(void);
    void set_limits(unsigned long limit1, unsigned long limit2);
    void set_L1_cache(VciCcVCacheWrapper2V1<vci_param, iss_t> *l1);
    ~VciProfiler();

private:

#define VCI_CMD_NR              4+7      // TODO: define vci_param::CMD_NR 


    struct cmd_info_s
    {
        unsigned long trans;
        unsigned long cost;
        unsigned long remote;
        unsigned long rcost;
        unsigned long limit1;
        unsigned long limit2;
        unsigned long rmax_time;
        unsigned long rmax_cost;
        unsigned long raddr;
        unsigned long lmax_time;
        unsigned long lmax_cost;
        unsigned long flits;
        unsigned long rflits;
        unsigned long distance;
        unsigned long max_dist;
        unsigned long d1_limit;
        unsigned long d2_limit;
    } m_cmd_tbl[VCI_CMD_NR]; 
    
    unsigned long m_index;
    unsigned long m_xWidth;
    unsigned long m_yWidth;
    unsigned long m_width;
    long m_x;
    long m_y;
    unsigned long m_bits;

    unsigned long m_tm_now;
    unsigned long m_tm_start;
    unsigned long m_last_cmd;
    unsigned long m_last_addr;
    unsigned long m_limit1;
    unsigned long m_limit2;
    unsigned long m_d1_limit;
    unsigned long m_d2_limit;
    unsigned long m_period;
    unsigned long m_threshold;
    unsigned long m_debug_cntr;
    bool m_isPending;
    bool m_isCMDPending;
    bool m_isPeriod;
    bool m_isRemote;
    bool m_isInstruction;
    bool m_isDebug;

    VciCcVCacheWrapper2V1<vci_param, iss_t> *m_l1;

    unsigned long m_exchange_cntr;
    unsigned long m_access_cntr;
    unsigned long m_remote_cntr;
    unsigned long m_cycles_cntr;
    
    //std::ofstream m_log;

    void transition();
};

}}

#endif /* SOCLIB_CABA_VCI_PROFILER_H */

// Local Variables:
// tab-width: 4
// c-basic-offset: 4
// c-file-offsets:((innamespace . 0)(inline-open . 0))
// indent-tabs-mode: nil
// End:

// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4

