/*
 * 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
 *
 */

#include "generic_cmd_fifo.h"

#define cmd_fifo(x) template<typename in, typename out, typename signal> x GenericCmdFifo<in, out, signal>

cmd_fifo(/**/)::GenericCmdFifo(sc_module_name name):
	       sc_module(name)
{
  SC_METHOD(transition);
  dont_initialize();
  sensitive << p_clk.pos();

  SC_METHOD(genMoore);
  dont_initialize();
  sensitive << p_clk.neg();

  DEBUG(NONE, STD, "[SECBUS] Building GenericFifoCmd (%s)\n",
	basename());
}

cmd_fifo(/**/)::~GenericCmdFifo()
{

}

cmd_fifo(void)::transition()
{
  if (!p_resetn)
  {
    fsm_s = FSM_IDLE;
    
    return;
  }

  DEBUG(TRACE, FSM, "[%s]\t\tFSM\t%u\n", basename(), (uint32_t)fsm_s.read());

  switch(fsm_s)
  {
  case FSM_IDLE:
    if (input.cmdval.read())
    {
      signals(input);
      signals.rspval = false;
      signals.cmdack = false;
      fsm_s = FSM_CMD;
    }
    break;

  case FSM_CMD:
    if (output.cmdack.read())
    {
      signals(output);
      fsm_s = FSM_WAIT;
    }
    break;
    
  case FSM_WAIT:
    if (output.rspval)
    {
      signals(output);
      fsm_s = FSM_IDLE;
    }
    break;
  }
}

cmd_fifo(void)::genMoore()
{
  input.rspval = false;
  input.cmdack = false;
  output.cmdval = false;

  switch(fsm_s)
  {
  case FSM_IDLE:
    input = signals;
    break;
    
  case FSM_CMD:
    output = signals;
    break;
    
  case FSM_WAIT:
    input = signals;
    break;
  }
}
