/* -*- c++ -*-
 * File         : vci_synthetic_initiator.h
 * Date         : 26/08/2010
 * Copyright    : UPMC / LIP6
 * Authors      : Christophe Choichillon
 * Version	: 2.0
 * 
 * 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>
#include <inttypes.h>
#include "generic_fifo.h"
#include "vci_initiator.h"
#include "soclib_endian.h"
#include "caba_base_module.h"
#include "int_tab.h"
#include "mapping_table.h"
#include "arithmetics.h"

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_BC_SEND,
      };

      enum bc_rsp_fsm_state_e{
      	BC_RSP_IDLE,
	BC_RSP_WAIT_RSP
      };


      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,
		const soclib::common::MappingTable &mt,
		const soclib::common::IntTab       &vci_index,
		const uint32_t length,    // Packet length (flit numbers)
		const uint32_t rho,       // Packets ratio on the network
		const uint32_t depth,     // Fifo depth
		const uint32_t xmesh,	
		const uint32_t ymesh,
		const uint32_t bc_period = 0, // Broadcast period, if no broadcast => 0
		const uint32_t xmin = 0, 
		const uint32_t xmax = 0,
		const uint32_t ymin = 0,
		const uint32_t ymax = 0
		);                                 

      ~VciSyntheticInitiator();

      void transition();

      void genMoore();

      uint32_t destAdress();

      uint32_t destAdress(uint32_t *rand_seed);

      void printStats();

      void print_trace();

    private:

      // Component attributes
      const size_t   			  m_length;		// Number of words to write
      const size_t			  m_rho;		// Rate of packets in the network wanted
      //const float			  m_rho;		// Rate of packets in the network wanted
      const size_t			  m_depth;     		// Fifo depth
      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;
      const size_t			  m_srcid;
      static const int 			  tab_size = 1 << vci_param::T;

      sc_signal<size_t>    		  r_count;                  // Numbers of words sent
      sc_signal<size_t>      		  r_npackets;		    // Total number of packets already sent
      sc_signal<uint64_t>	  	  r_start_latency1;         // Start time of sending packet wanted
      sc_signal<uint64_t> 	  	  r_start_latency2;         // Start time of sending packet
      sc_signal<uint64_t>		  r_latency1;		    // Average latency wanted
      sc_signal<uint64_t>		  r_latency2;		    // Average latency 
      sc_signal<addr_t>			  r_address_to_send; 	    // Address to send the write command
      sc_signal<uint32_t>		  r_local_seed;
      sc_signal<int>			  r_id_to_send;

      sc_signal<uint64_t>		  r_start_latency_bc;
      sc_signal<uint64_t>		  r_latency_bc;
      sc_signal<uint64_t>		  r_nb_bc;

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

      sc_signal<int>           	r_cmd_fsm;

      sc_signal<int>           	r_bc_rsp_fsm;
	
      sc_signal<size_t>	       	r_index;

      sc_signal<bool>	       	r_broadcast_req;

      sc_signal<bool>	       	r_broadcast_rsp;

      sc_signal<uint32_t>	r_bc_nrsp;		    // Expected number of responses for a broadcast command

      sc_signal<uint64_t>	**r_req_id;


    }; // end class VciSyntheticInitiator
 
  }}

#endif
