#include "mux.h"

void SecurityContextControllerMux::ps()
{
  if (!reset)
	{
		state = IDLE;
	}

  switch(state)
	{
		case IDLE:
			if (in1.enable)
			{
				state = IN1;
			}
			else if (in2.enable)
			{
				state = IN2;
			}
			break;

		case IN1:
			state = IDLE;
			break;

		case IN2:
			state = IDLE;
			break;
  }
}

void SecurityContextControllerMux::pc()
{
/*	if (in1.enable)
	{

        out.cmd			= in1.cmd;
		out.initiator	= in1.initiator;
		out.address		= in1.address;
		out.enable		= in1.enable;	
	}
	else if (in2.enable)
	{
		out.cmd			= in2.cmd;
		out.initiator	= in2.initiator;
		out.address		= in2.address;
		out.enable		= in2.enable;
	}
	else
		out.enable		= false;
 */
	switch(state)
	{
		case IDLE:
			out.enable = false;
			break;

		case IN1:
			out.cmd = in1.cmd;
			out.initiator = in1.initiator;
			out.address = in1.address;
			out.enable = in1.enable;	
			break;

		case IN2:
			out.cmd = in2.cmd;
			out.initiator = in2.initiator;
			out.address = in2.address;
			out.enable = in2.enable;
			break;
	}
}

void SecurityContextRegisterMux::pc()
{	
	if (in1.enable)
	{
		out.enable		    	= in1.enable;
    out.sel			      	= in1.sel;
		out.page_address  	= in1.page_address;
		out.sp_address    	= in1.sp_address;
		out.spspe_address  	= in1.spspe_address;
		for(unsigned int i=0;i<PSPE_SIZE;i++)
		{
      out.spspe[i]		      	= in1.spspe[i];
		  out.mpspe[i]		      	= in1.mpspe[i];
    }
		for(unsigned int i=0;i<SP_SIZE;i++)
		  out.sp[i]			      	= in1.sp[i];
	}
	else if (in2.enable)
	{
		out.enable		    	= in2.enable;
    out.sel			      	= in2.sel;
		out.page_address  	= in2.page_address;
		out.sp_address    	= in2.sp_address;
		out.spspe_address  	= in2.spspe_address;
		for(unsigned int i=0;i<PSPE_SIZE;i++)
		{
      out.spspe[i]		      	= in2.spspe[i];
		  out.mpspe[i]		      	= in2.mpspe[i];
    }
		for(unsigned int i=0;i<SP_SIZE;i++)
		  out.sp[i]			      	= in2.sp[i];
	}
	else
		out.enable			= false;

}

void DataRegisterMux2::pc()
{	
	if (in1.enable)
	{
		out.enable	= in1.enable;
		out.flush	= in1.flush;
		out.address = in1.address;
		out.be		= in1.be;
		for(unsigned int i=0;i<SIZE_256_IN_WORDS;i++)
			out.data[i] =  in1.data[i];
	}
	else if (in2.enable)
	{
		out.enable	= in2.enable;
		out.flush	= in2.flush;
		out.address = in2.address;
		out.be		= in2.be;
		for(unsigned int i=0;i<SIZE_256_IN_WORDS;i++)
			out.data[i] =  in2.data[i];
	}
	else
		out.enable	= false;
}

void DataRegisterMux3::pc()
{	
	if (in1.enable)
	{
		out.enable	= in1.enable;
		out.flush	= in1.flush;
		out.address = in1.address;
		out.be		= in1.be;
		for(unsigned int i=0;i<SIZE_256_IN_WORDS;i++)
			out.data[i] =  in1.data[i];
	}
	else if (in2.enable)
	{
		out.enable	= in2.enable;
		out.flush	= in2.flush;
		out.address = in2.address;
		out.be		= in2.be;
		for(unsigned int i=0;i<SIZE_256_IN_WORDS;i++)
			out.data[i] =  in2.data[i];
	}
	else if (in3.enable)
	{
		out.enable	= in3.enable;
		out.flush	= in3.flush;
		out.address = in3.address;
		out.be		= in3.be;
		for(unsigned int i=0;i<SIZE_256_IN_WORDS;i++)
			out.data[i] =  in3.data[i];
	}
	else
		out.enable	= false;
}

void CacheControllerMux::pc()
{	
	if (sc_cmd.enable)
	{
        out_cmd.enable		= sc_cmd.enable;
		out_cmd.address		= sc_cmd.address;
		out_cmd.cmd			= sc_cmd.cmd;
		out_wdata.data[0]	= sc_wdata.data[0];
		out_wdata.data[1]	= sc_wdata.data[1];	
	}
	else if (ht_cmd.enable)
	{
		out_cmd.enable		= ht_cmd.enable;
		out_cmd.address		= ht_cmd.address;
		out_cmd.cmd			= ht_cmd.cmd;
		out_wdata.data[0]	= ht_wdata.data[0];
		out_wdata.data[1]	= ht_wdata.data[1];	
	}
	else
		out_cmd.enable = false;
}

void SecurityControllerMux::pc()
{	
	if (sp_cmd.enable)
	{
		out_cmd.plen				= sp_cmd.plen;
        out_cmd.cmd					= sp_cmd.cmd;
		out_cmd.start_address		= sp_cmd.start_address;
		out_cmd.enable				= sp_cmd.enable;
		out_data.data[0]			= sp_data.data[0];
		out_data.data[1]			= sp_data.data[1];
		out_data.data[2]			= sp_data.data[2];
		out_data.data[3]			= sp_data.data[3];
	}
	else if (pspe_cmd.enable)
	{
		out_cmd.plen				= pspe_cmd.plen;
		out_cmd.cmd					= pspe_cmd.cmd;
		out_cmd.start_address		= pspe_cmd.start_address;
		out_cmd.enable				= pspe_cmd.enable;
		out_data.data[0]			= pspe_data.data[0];
		out_data.data[1]			= pspe_data.data[1];
	}
	else
		out_cmd.enable				= false;
}

void MemoryControllerMux::ps()
{
  if (!reset)
	{
		state = IDLE;
	}

  switch(state)
	{
		case IDLE:
      if (security_controller_cmd.enable)
			{
				state = SC;
			}
			else if (hash_cache_controller_cmd.enable)
			{
				state = HC;
			}
			else if (hash_tree_controller_cmd.enable)
			{
				state = HT;
			}
			else if (mac_controller_cmd.enable)
			{
				state = MC;
			}
			else if (mac_cache_controller_cmd.enable)
			{
				state = MCC;
			}
		  break;

		case SC:
		case HC:
		case HT:
		case MC:
		case MCC:
		default:
	    state = IDLE;
			break;
	}
}

void MemoryControllerMux::pc()
{	
/*  switch(state)
	{
		case IDLE:
		  memory_out_cmd.enable = false;
			break;

	  case SC:
			memory_out_cmd.plen = security_controller_cmd.plen;
			memory_out_cmd.cmd = security_controller_cmd.cmd;
			memory_out_cmd.start_address = security_controller_cmd.start_address;
			memory_out_cmd.enable = security_controller_cmd.enable;
			memory_out_cmd.id = security_controller_cmd.id;
		  break;

		case HC:
			memory_out_cmd.plen	= hash_cache_controller_cmd.plen;
			memory_out_cmd.cmd = hash_cache_controller_cmd.cmd;
			memory_out_cmd.start_address = hash_cache_controller_cmd.start_address;
			memory_out_cmd.enable = hash_cache_controller_cmd.enable;
			memory_out_cmd.id = hash_cache_controller_cmd.id;
			break;

		case HT:
			memory_out_cmd.plen = hash_tree_controller_cmd.plen;
			memory_out_cmd.cmd = hash_tree_controller_cmd.cmd;
			memory_out_cmd.start_address = hash_tree_controller_cmd.start_address;
			memory_out_cmd.enable = hash_tree_controller_cmd.enable;
			memory_out_cmd.id = hash_tree_controller_cmd.id;
		  break;

		case MC:
			memory_out_cmd.plen = mac_controller_cmd.plen;
			memory_out_cmd.cmd = mac_controller_cmd.cmd;
			memory_out_cmd.start_address = mac_controller_cmd.start_address;
			memory_out_cmd.enable = mac_controller_cmd.enable;
			memory_out_cmd.id = mac_controller_cmd.id;
		  break;

		case MCC:
			memory_out_cmd.plen = mac_cache_controller_cmd.plen;
			memory_out_cmd.cmd = mac_cache_controller_cmd.cmd;
			memory_out_cmd.start_address = mac_cache_controller_cmd.start_address;
			memory_out_cmd.enable = mac_cache_controller_cmd.enable;
			memory_out_cmd.id = mac_cache_controller_cmd.id;
		  break;

		default:

		  break;
	}*/
	if (security_controller_cmd.enable)
	{
		memory_out_cmd.plen				= security_controller_cmd.plen;
		memory_out_cmd.cmd				= security_controller_cmd.cmd;
		memory_out_cmd.start_address	= security_controller_cmd.start_address;
		memory_out_cmd.enable			= security_controller_cmd.enable;
		memory_out_cmd.id				= security_controller_cmd.id;

	}
	else if (hash_cache_controller_cmd.enable)
	{
		memory_out_cmd.plen				= hash_cache_controller_cmd.plen;
		memory_out_cmd.cmd				= hash_cache_controller_cmd.cmd;
		memory_out_cmd.start_address	= hash_cache_controller_cmd.start_address;
		memory_out_cmd.enable			= hash_cache_controller_cmd.enable;
		memory_out_cmd.id				= hash_cache_controller_cmd.id;
	}
	else if (mac_cache_controller_cmd.enable)
	{
		memory_out_cmd.plen				= mac_cache_controller_cmd.plen;
		memory_out_cmd.cmd				= mac_cache_controller_cmd.cmd;
		memory_out_cmd.start_address	= mac_cache_controller_cmd.start_address;
		memory_out_cmd.enable			= mac_cache_controller_cmd.enable;
		memory_out_cmd.id				= mac_cache_controller_cmd.id;
	}
	else if (hash_tree_controller_cmd.enable)
	{
		memory_out_cmd.plen				= hash_tree_controller_cmd.plen;
		memory_out_cmd.cmd				= hash_tree_controller_cmd.cmd;
		memory_out_cmd.start_address	= hash_tree_controller_cmd.start_address;
		memory_out_cmd.enable			= hash_tree_controller_cmd.enable;
		memory_out_cmd.id				= hash_tree_controller_cmd.id;
	}
	else if (mac_controller_cmd.enable)
	{
		memory_out_cmd.plen				= mac_controller_cmd.plen;
		memory_out_cmd.cmd				= mac_controller_cmd.cmd;
		memory_out_cmd.start_address	= mac_controller_cmd.start_address;
		memory_out_cmd.enable			= mac_controller_cmd.enable;
		memory_out_cmd.id				= mac_controller_cmd.id;
	}
	else
		memory_out_cmd.enable			= false;
}
void CBCMux::pc()
{	

	if (mac_cmd.enable)
	{
		out_cmd.imode			= mac_cmd.imode;
		out_cmd.stage_0			= mac_cmd.stage_0;
		out_cmd.address			= mac_cmd.address;
		out_cmd.cmode			= mac_cmd.cmode;
		out_cmd.key				= mac_cmd.key;
		out_cmd.enable			= mac_cmd.enable;
		out_cmd.size			= mac_cmd.size;
		out_cmd.index			= mac_cmd.index;
		for(unsigned int i=0;i<8;i++)
			out_data.data[i]	= mac_data.data[i];
		for(unsigned int i=0;i<2;i++)
			out_iv.data[i]		= mac_iv.data[i];

	}
	else if (hash_cmd.enable)
	{
		out_cmd.imode			= hash_cmd.imode;
		out_cmd.cmode			= hash_cmd.cmode;
		out_cmd.stage_0			= hash_cmd.stage_0;
		out_cmd.address			= hash_cmd.address;
		out_cmd.key				= hash_cmd.key;
		out_cmd.enable			= hash_cmd.enable;
		out_cmd.size			= hash_cmd.size;
		out_cmd.index			= hash_cmd.index;
		for(unsigned int i=0;i<12;i++)
			out_data.data[i]	= hash_data.data[i];
		for(unsigned int i=0;i<2;i++)
			out_iv.data[i]		= hash_iv.data[i];
	}
	else if (tool_cmd.enable)
  {
		out_cmd.imode = tool_cmd.imode;
		out_cmd.cmode			= tool_cmd.cmode;
		out_cmd.stage_0			= tool_cmd.stage_0;
		out_cmd.address			= tool_cmd.address;
		out_cmd.key				= tool_cmd.key;
		out_cmd.enable			= tool_cmd.enable;
		out_cmd.size			= tool_cmd.size;
		out_cmd.index			= tool_cmd.index;
		for(unsigned int i=0;i<12;i++)
			out_data.data[i]	= tool_data.data[i];
		for(unsigned int i=0;i<2;i++)
			out_iv.data[i]		= tool_iv.data[i];

  }
		else
		out_cmd.enable			= false;

}

void IntegrityControllerMux::pc()
{
	if (in1.enable)
	{
		out.cmd			= in1.cmd;
		out.address		= in1.address;
		out.enable		= in1.enable;	
	}
	else if (in2.enable)
	{
		out.cmd			= in2.cmd;
		out.address		= in2.address;
		out.enable		= in2.enable;
	}
	else
		out.enable = false;


};


