///////////////////////////////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------------------
//-- Title      : AXI Master Interface
//-------------------------------------------------------------------------------
//-- File       : AXI_IF.v
//-- Author     : Corporate Applications Engineering
//-- Company    : Microsemi Corporation
//-- Device     : SmartFusion2
//-- Standard   : Verilog
//-------------------------------------------------------------------------------
//-- Description: This code implementes the AXI master logic to write the data to  
//--              MDDR through DDR_FI and does 64bit burst transactions.
//-------------------------------------------------------------------------------
//-- Copyright (c) 2013   Microsemi Corporation
//--                      All rights reserved.
//-------------------------------------------------------------------------------
//-- Revisions  : V1.0
//-------------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////////////////////// 

module AXI_IF(
	//input DRAM_Ready,
	input 				CLK,
	input 				RESETn,

	input 				WRITE,
	input		[63:0]	DATA_IN,
	output	reg			AXI_BUSY,	

  	// Write Address Channel (WAC)
	output		[3:0]   AWID, 
	output	reg [31:0]  AWADDR, 
  	output  	[3:0]   AWLEN, 
  	output reg 	[2:0]   AWSIZE, 
  	output  	[1:0]   AWLOCK,  
  	output reg 	[1:0]   AWBURST, 
  	output reg          AWVALID,  
  	input               AWREADY,  
  	// Write Data Channel (RDC)
  	output  [3:0]       WID, 
  	output  [7:0]       WSTRB,
  	output reg          WLAST,
  	output reg          WVALID,
  	output reg [63:0]   WDATA, 
  	input               WREADY, 	
  	// Write Response Channel (WRC)
 	input [3:0]         BID,
	input [1:0]         BRESP,  
	input               BVALID,	
	output reg          BREADY,
  // Read Address Channel (RAC)
	output [3:0]        ARID, 
	output [31:0]       ARADDR, 
	output [3:0]        ARLEN, 
    output [1:0]        ARSIZE, 
    output [1:0]        ARLOCK, 
    output [1:0]        ARBURST, 
    output              ARVALID, 
    input               ARREADY, 
  // Read Data Channel (RDC)
    input [3:0]         RID,
    input [63:0]        RDATA, 
    input [1:0]         RRESP,
    input               RLAST,
    input               RVALID,
    output reg          RREADY);

// AXI FSM States
reg [2:0] axi_fsm_current_state;
parameter [2:0] Idle_0 = 3'b000, Idle_1 = 3'b001, Write_0 = 3'b010, Write_1 = 3'b011, Bresp_0 = 3'b100;

reg   [31:0] AWADDR_int;
reg   [63:0] WDATA_int;

assign AWLEN  = 4'b0000;
assign AWLOCK = 2'b00;
assign AWID  = 4'b0000;
assign WID = 4'b0000;
assign WSTRB = 8'hFF;

always@(posedge CLK, negedge RESETn)
begin	
	if(RESETn == 1'b0 )
		begin
		 AWADDR_int 	<= 32'hA0000000;
         AWADDR         <=  0;
         AWVALID        <=  0;         
		 AWSIZE 		<= 3'b000;		 
		 AWBURST 		<= 2'b00;	
         WVALID         <=  0;
         WLAST          <=  0;
         WDATA_int      <=  0;
         WDATA          <=  0;
         BREADY         <=  0;
		 AXI_BUSY		<= 1'b1;
		 axi_fsm_current_state   <=  Idle_0;
		end
	else
		begin
			case (axi_fsm_current_state)
			Idle_0:
			begin
				AXI_BUSY				<= 1'b0;
				axi_fsm_current_state   <=  Idle_1;
			end
			Idle_1:
			begin
				if ( WRITE == 1'b1)
				begin
				AWSIZE 					<= 3'b011;
				AWBURST 				<= 2'b01;
				AWADDR 					<= AWADDR_int;
				AWVALID 				<= 1'b1;
				BREADY 					<= 1'b0;
				WDATA_int  				<= DATA_IN;
				AXI_BUSY				<= 1'b1;
				axi_fsm_current_state   <= Write_0;
				end
				else
				begin
				axi_fsm_current_state   <= Idle_1;
				end
			end
			Write_0:
			begin
				if (AWREADY == 1'b1)
				begin
				AWVALID 				<= 1'b0;
				WDATA  					<= WDATA_int;				
				WVALID 					<= 1'b1;
				WLAST  					<= 1'b1;
				axi_fsm_current_state   <= Write_1;
				end
				else
				begin
				axi_fsm_current_state   <= Write_0;
				end
			end
			Write_1:
			begin
				if (WREADY == 1'b1)
				begin
				WVALID 					<= 1'b0;
				WLAST  					<= 1'b0;
				axi_fsm_current_state   <= Bresp_0;
				end
				else
				begin
				axi_fsm_current_state   <= Write_1;
				end
			end
			Bresp_0:
			begin
				if (BVALID == 1'b1)
				begin
				BREADY 					<= 1'b1;
				AXI_BUSY				<= 1'b0;
		 		AWADDR_int 				<= AWADDR_int + 8;		 		
				axi_fsm_current_state   <= Idle_1;
				end
				else
				begin
				axi_fsm_current_state   <=  Bresp_0;
				end
			end		
			
			endcase
	end
end
endmodule
