/*-------------------------------------------------------------------------------
 Title      : COM Interface
-------------------------------------------------------------------------------
 File       : Control_Logic.v
 Author     : Corporate Applications Engineering
 Company    : Microsemi Corporation
 Device     : IGLOO2
 Standard   : Verilog
-------------------------------------------------------------------------------
 Description: It receives the COMMAND from PC GUI and send to COMMAND Decoder.
              Once AXI master completes the data transfer, it read the throughput
              from LSRAM and send to PC.
-------------------------------------------------------------------------------
 Copyright (c) 2014   Microsemi Corporation
                      All rights reserved.
-------------------------------------------------------------------------------
 Revisions  : V1.0
-------------------------------------------------------------------------------*/

module Control_Logic( 
	input wire		 CLK,
	input wire		 RESET_N,
	input wire		 TX_RDY,
	input wire		 RX_RDY,
	input wire		 AXI_BUSY,
	input wire [7:0] DATA_IN,
	input wire [7:0] RAM_RD,

	output reg		  RAM_REN,
	output reg		  WEN,
	output reg		  OEN,
	output reg  [7:0] DATA_OUT,
	output wire [7:0] COMMAND,
	output reg  [3:0] RAM_RADDR
);

reg [3:0] fsm;
reg [3:0] cnt16;
reg [7:0] CMD;
reg cnt_en;

assign COMMAND = CMD;

always @(posedge CLK or negedge RESET_N)
if(!RESET_N)
 begin
    DATA_OUT  <= 8'b00000000;
	CMD       <= 8'b00000000;
    RAM_RADDR <= 4'b1111;
	WEN       <= 1'b1;
	OEN       <= 1'b1;
	RAM_REN   <= 1'b0;
    cnt_en    <= 1'b0;
	fsm       <= 4'b0000; 
 end
else
 begin
   case (fsm)
    4'b0000 :  
      begin
		DATA_OUT  <= 8'b00000000;
		CMD       <= 8'b00000000;
		RAM_RADDR <= 4'b1111;
		WEN       <= 1'b1;
		OEN       <= 1'b1;
		RAM_REN   <= 1'b0;
		cnt_en    <= 1'b0;			
		
        if(RX_RDY == 1'b1) 
		  begin
            if(DATA_IN == 8'b1100011) /* 'c' */
              begin
                OEN  <= 1'b0;
                fsm  <= 4'b0001;                   
              end
            else
              begin
                OEN  <= 1'b0;
                fsm  <= 4'b0000;
              end
		  end
        else
		  begin
            OEN <= 1'b1;
		    fsm <= 4'b0000;
		  end		
	  end  
	4'b0001 :      /* Acknowledge 'a' */ 
      begin
	    OEN <= 1'b1;
        if(TX_RDY == 1'b1)
          begin
            DATA_OUT <= 8'b01100001; /* 'a' */
            WEN      <= 1'b0;
			fsm      <= 4'b0010;
          end
        else
          begin
            WEN <= 1'b1;
            fsm <= 4'b0001;
          end	  
	  end
	4'b0010 :      
      begin
	    WEN  <= 1'b1;
		fsm  <= 4'b0011;  
	  end
	4'b0011 :  /* Reading the Command */
      begin
        if(RX_RDY == 1'b1) 
		  begin
            OEN     <= 1'b0;
			CMD     <= DATA_IN;
			cnt_en  <= 1'b1;
            fsm     <= 4'b0100;                   
		  end
        else
		  begin
            OEN     <= 1'b1;
			CMD     <= 8'b00000000;
			cnt_en  <= 1'b0;
            fsm     <= 4'b0011; 
		  end
	  end
    4'b0100 :  /* Holding the command for 15 clock cycle */
      begin
	  	OEN <= 1'b1;
		if(cnt16 < 4'b1111) 
		  begin
            fsm     <= 4'b0100;
		  end
	    else
		  begin
			cnt_en  <= 1'b0;
			CMD     <= 8'b00000000;
            fsm     <= 4'b0101;
		  end
	  end
    4'b0101 :  /* Sending the throughput values to CoreUART  */
      begin
			RAM_RADDR <= RAM_RADDR + 1;
            fsm       <= 4'b0110;    
	  end 
	4'b0110 :  
      begin
        if(AXI_BUSY == 1'b0) 
		  begin
			RAM_REN   <= 1'b1;
            fsm       <= 4'b1010;    
		  end
        else
		  begin
            fsm      <= 4'b0110;           
		  end
	  end
    4'b1010 :  
      begin
            fsm       <= 4'b0111;    
	  end 

    4'b0111 :  
      begin
		if(TX_RDY == 1'b1)
		  begin
            DATA_OUT <= RAM_RD;  
            WEN      <= 1'b0;	
            fsm      <= 4'b1000;			
		  end
		else
		  begin
            fsm      <= 4'b0111; 
		  end
	  end
    4'b1000 :  
      begin
        if(TX_RDY == 1'b0)
		  begin
			RAM_REN <= 1'b0;
            WEN     <= 1'b1;
			if(RAM_RADDR == 4'b1111)
			  begin
                fsm  <= 4'b1001;
			  end
			else
			  begin
               fsm   <= 4'b0101;  
			  end
		  end
		else
		  begin
            fsm      <= 4'b1000;	
		  end
	  end 
	4'b1001 :      /* Operation Completed 'c' */ 
      begin
        if(TX_RDY == 1'b1)
          begin
            DATA_OUT <= 8'b1100011; /* 'c' */
            WEN      <= 1'b0;	
            fsm      <= 4'b0000;	
          end
        else
          begin
            fsm      <= 4'b1001; 
          end	  
	  end	  

    default : fsm <= 4'b0000;    
  endcase
end

always @(posedge CLK or negedge RESET_N)
 if(!RESET_N)
   cnt16 = 4'b0;
 else if(cnt_en)
   cnt16 = cnt16 + 1;
 else
   cnt16 = 4'b0;

endmodule


