/*
 * SecBus - This file is part of SecBus
 * Copyright (C) 2012 - Telecom ParisTech
 * 
 * This file must be used under the terms of the CeCILL.
 * This source file is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at    
 * http://www.cecill.info/licences/Licence_CeCILL_V1.1-US.txt
 *
 */

#ifndef _VCI_SPLIT_H
#define _VCI_SPLIT_H

#include <systemc>
#include "vci_initiator.h"
#include "vci_target.h"

#include "my_interfaces.h"

template<typename vci_param>
SC_MODULE(VciSplit)
{
protected:
  SC_HAS_PROCESS(VciSplit);

public:
  sc_in<bool> p_clk;
  sc_in<bool> p_resetn;

  soclib::caba::VciTarget<vci_param> p_vci_initiator;

  soclib::caba::VciInitiator<vci_param> p_vci_target_sec;
  soclib::caba::VciInitiator<vci_param> p_vci_target_unsec;

  sc_in<bool>         p_enable;
  sc_in<unsigned int> p_addr;
  sc_in<unsigned int> p_size;

  VciSplit(sc_module_name name);

private:
  enum fsm_state_e
  {
    FSM_IDLE, // Waiting for requests from initiator
    FSM_CMD,  // Forwarding requests, responses and acknowledges between initiator and currently selected target
    FSM_RSP   // Forwarding responses and acknowledges between initiator and currently selected target
  };

  sc_signal<int> fsm_s;
  unsigned int m_addr;
  unsigned int m_size;
  bool         m_enable;

  sc_signal<bool> sec_s;
  
  void transition();
  void genMealy_i2t(); // Initiator to targets
  void genMealy_t2i(); // Targets to initiator

  // Initiator to target forwarding (but cmdval and rspack) 
  void i2t(soclib::caba::VciInitiator<vci_param> &t)
  {
    t.address = p_vci_initiator.address;
    t.be      = p_vci_initiator.be;
    t.cfixed  = p_vci_initiator.cfixed;
    t.clen    = p_vci_initiator.clen;
    t.cmd     = p_vci_initiator.cmd;
    t.cons    = p_vci_initiator.cons;
    t.contig  = p_vci_initiator.contig;
    t.eop     = p_vci_initiator.eop;
    t.pktid   = p_vci_initiator.pktid;
    t.plen    = p_vci_initiator.plen;
    t.srcid   = p_vci_initiator.srcid;
    t.trdid   = p_vci_initiator.trdid;
    t.wdata   = p_vci_initiator.wdata;
    t.wrap    = p_vci_initiator.wrap;
  }

  // Target to initiator forwarding (but rspval and cmdack) 
  void t2i(soclib::caba::VciInitiator<vci_param> &t)
  {
    p_vci_initiator.rdata   = t.rdata;
    p_vci_initiator.reop    = t.reop;
    p_vci_initiator.rerror  = t.rerror;
    p_vci_initiator.rpktid  = t.rpktid;
    p_vci_initiator.rsrcid  = t.rsrcid;
    p_vci_initiator.rtrdid  = t.rtrdid;
  }
};

#endif
