#ifndef TSAR_CLUSTER_V1_H
#define TSAR_CLUSTER_V1_H

#include <systemc.h>
#include <iostream>

#include "mapping_table.h"
#include "mips32.h"
#include "vci_multi_tty.h"
#include "vci_mem_cache_v1.h"
#include "vci_cc_xcache_wrapper_v1.h"
#include "vci_xicu.h"
#include "vci_simple_ring_fast.h"
#include "gdbserver.h"
#include "vci_initiator.h"

///////////////////////////////////////////////////////////
//     TGTID & SRCID definition in direct space
// For all components:  global TGTID = global SRCID = cluster_index
// For processors, the local SRCID is between 0 & nprocs-1

#define MEMC_TGTID	  0
#define XICU_TGTID	  1
#define MTTY_TGTID	  2

#define PROC_SRCID    0

namespace soclib { 
  namespace caba {

    template <typename vci_param, size_t cmd_width, size_t rsp_width>
    class TsarClusterV1 : public soclib::caba::BaseModule {
      public:
        TsarClusterV1(
          sc_module_name nm,

          // Cluster Index
          int cluster_idx,

          // Dspin Routers parameters
          int infifo_depth,
          int outfifo_depth,
          int x_local,
          int y_local,

          // Bits for global routing
          size_t x_width,
          size_t y_width,

          // Mapping tables
          const MappingTable & md,
          const MappingTable & mc,
          const MappingTable & mx,

          // Processor Number
          size_t nprocs,
          size_t max_nprocs,
         
          // Cache L1 sizes
          size_t iways,
          size_t isets,
          size_t iwords,
          size_t dways,
          size_t dsets,
          size_t dwords,

          // MemCache sizes
          size_t mcways,
          size_t mcsets,
          size_t mcwords,

          int    is_io,

          Loader & loader
        );

        void print_trace();

        ~TsarClusterV1();

      private:
        typedef soclib::common::GdbServer<soclib::common::Mips32ElIss> proc_iss;

        ///////////////////////////////////////////////////////////
        // Components

        VciSimpleRingFast<vci_param,cmd_width,rsp_width> * ringd;
        VciSimpleRingFast<vci_param,cmd_width,rsp_width> * ringc;

        VciCcXCacheWrapperV1<vci_param, proc_iss> ** procs;
        VciMemCacheV1<vci_param>                  *  memc;
        VciXicu<vci_param>                        *  xicu;
        VciMultiTty<vci_param>                    *  mtty;

        ////////////////////////////////////////////////////////////
        // Signals

        // Direct VCI Signals
        VciSignals<vci_param> * signal_vci_ini_d;
        VciSignals<vci_param> * signal_vci_tgt_d;

        // Coherence VCI Signals
        VciSignals<vci_param> * signal_vci_ini_c;
        VciSignals<vci_param> * signal_vci_tgt_c;

        // Interruptions
        sc_signal<bool> * signal_proc_irq;
        sc_signal<bool>   signal_mtty_irq;

        sc_signal<bool>   signal_false;

        size_t m_nprocs;

      public:

        ////////////////////////////////////////////////////////////
        // Ports

        sc_in<bool> p_clk;
        sc_in<bool> p_resetn;

        soclib::caba::VciInitiator<vci_param>   p_vci_ixr;
    };
  }
}

#endif

// vim: tabstop=2 : shiftwidth=2 : expandtab
