/* -*- c++ -*-
 * File         : vci_synthetic_initiator.h
 * Date         : 26/08/2010
 * Copyright    : UPMC / LIP6
 * Authors      : Christophe Choichillon
 *
 * 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
 *
 * Maintainers: christophe.choichillon@lip6.fr
 */

#ifndef SOCLIB_CABA_SYNTHETIC_INITIATOR_H
#define SOCLIB_CABA_SYNTHETIC_INITIATOR_H

#include <systemc>

namespace soclib {  namespace caba {
    using namespace sc_core;

    template<typename vci_param>
    class VciSyntheticInitiator
      : public soclib::caba::BaseModule
    {
      typedef uint32_t addr_t;
      typedef uint32_t data_t;
      typedef uint32_t tag_t;
      typedef uint32_t size_t;
      typedef uint32_t be_t;
      typedef uint32_t copy_t;


      /* States of the GENERATOR fsm */
      enum vci_fsm_state_e{
	VCI_IDLE,
	VCI_SINGLE_SEND,
	VCI_SINGLE_RECEIVE,
	VCI_BC_SEND,
	VCI_BC_RECEIVE
      };
      enum gen_fsm_state_e{
	A_IDLE,
	A_DATA
      };

      uint64_t	   m_cpt_cycles;            // Counter of cycles 
      

    protected:

      SC_HAS_PROCESS(VciSyntheticInitiator);
    
    public:
      sc_in<bool> 			  	p_clk;
      sc_in<bool> 			  	p_resetn;
      soclib::caba::VciInitiator<vci_param> 	p_vci;	

      VciSyntheticInitiator(
		sc_module_name name,
		size_t length,    // Packet length (flit numbers)
		float  rho,       // Packets ratio on the network
		size_t depth,     // Fifo depth
		size_t x,	  // X location of the synthetic initiator
		size_t y,	  // Y location of the synthetic initiator
		size_t xmesh,	
		size_t ymesh,
		size_t bc_period, // Broadcast period, if no broadcast => 0
		size_t xmin, 
		size_t xmax,
		size_t ymin,
		size_t ymax,
		const soclib::common::IntTab &vci_index
		);                                 

      ~VciSyntheticInitiator();

      void transition();

      void genMoore();

      void destAdress(size_t X_local, size_t Y_local, size_t &X_dest, size_t &Y_dest);

    private:

      // Component attributes
      const size_t   			  m_length;		// Number of flits of a packet
      const size_t			  m_rho;		// Rate of packets in the network wanted
      const size_t			  m_depth;     		// Fifo depth
      const size_t			  m_x;			// X location
      const size_t			  m_y;			// Y location
      const size_t			  m_xmesh;	
      const size_t			  m_ymesh;
      const size_t			  m_bc_period; 		// Broadcast period, if no broadcast => 0
      const size_t			  m_xmin; 
      const size_t			  m_xmax;
      const size_t			  m_ymin;
      const size_t			  m_ymax;

      size_t       m_count;
      size_t       m_npackets;		    // Total number of packets already sent

      // Fifo transmitting date to the VCI FSM
      GenericFifo<uint64_t>    m_date_fifo;

      sc_signal<int>         r_vci_fsm;
	
      sc_signal<size_t>	     r_index;

      sc_signal<bool>	     r_broadcast_req;

    }; // end class VciSyntheticInitiator
 
  }}

#endif
