`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    14:32:28 11/22/2014 
// Design Name: 
// Module Name:    ADC 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module ADC(
    input clk,                   // main clock
    input clk_spi,               // spi clock 4MHz
    //input [7:0] ir,
    //input [2:0] transfer_length, // 1 to 5
    input [23:0] data_w,
    output [23:0] data_r,
    input start,
    output done,
    output sclk,
    output cs,
    output mosi,
    input miso
    );

  
reg start_spi = 0;
reg start_delay = 0;
reg done_spi = 0;
reg spi_valid = 0;
reg [7:0] spi_valid_cnt = 0;
reg spi_valid_ff = 0;
reg mosi_t = 0;
reg [23:0] mosi_o = 0;
reg [1:0] state_done = 0;
reg [23:0]data_r_t = 0;

//wire [5:0] spi_valid_max = transfer_length << 3;

assign sclk = (spi_valid & spi_valid_ff & clk_spi);
assign cs = ~spi_valid;

always @(posedge clk)
begin
    if(start)
        start_spi <= 1'b1;
    else if(spi_valid)
        start_spi <= 1'b0;
end


always @(posedge clk_spi)
begin
    if(start_spi)
    begin
        start_delay <= 1'b1;
        if(start_delay != 0)
        begin
            spi_valid <= 1'b1;
            start_delay <= 1'b0;
        end
    end
    else if(done_spi)
        spi_valid <= 1'b0;
end

always @(posedge clk_spi)
begin
    spi_valid_ff <= spi_valid;
end

always @(posedge clk_spi)
begin
//    if(~spi_valid | done_spi)
		if(!spi_valid | done_spi)
        spi_valid_cnt <= 8'd0;
    else
        spi_valid_cnt <= spi_valid_cnt + 1;
end

always @(posedge clk_spi) //Total data packet!
begin
//    if(spi_valid_cnt == (spi_valid_max - 1))
	if(spi_valid_cnt == 6'd23)
        done_spi <= 1'b1;
    else
        done_spi <= 1'b0;
end

//////////////////////////////////////////////////////////
// data output processing
//////////////////////////////////////////////////////////
always @(negedge clk_spi)
begin
    if(spi_valid)
    begin
        mosi_t <= mosi_o[23];
        mosi_o <= mosi_o << 1;
    end
	 else
	     mosi_o <= data_w[23:0];
end
assign mosi = mosi_t;

/////////////////////////////////////////////////////////////////////
// done signal generation
/////////////////////////////////////////////////////////////////////
always @(posedge clk)
begin
    case(state_done)
        2'b00:
            begin
                if(spi_valid == 1)
                    state_done <= 1;
            end
        2'b01:
            begin
                if(spi_valid == 0)
                    state_done <= 2;
            end
        2'b10:
            state_done <= 0;
    endcase
end

assign done = (state_done == 2)?1'b1:1'b0;

////////////////////////////////////////////////////////////////////
// read data processing
////////////////////////////////////////////////////////////////////
always @(posedge clk_spi)
begin
			
			if((spi_valid_cnt >= 12) && (spi_valid_cnt <=23))
			begin    
				 data_r_t <= {data_r_t[23:0],miso};
			end
//	if(null_r &&(spi_valid_cnt <=24))
//	begin
//		data_r_t <= {data_r_t[23:0],miso};
//	end 

end

assign data_r = data_r_t;



endmodule