/////////////////////////////////////////////////////////////////////////////////
//
// assume 16x sampling rate
//
//
/////////////////////////////////////////////////////////////////////////////////

module serialin(
       input         din, clk, enable,
       output reg    done,
       output reg [59:0] dout);

   reg [7:0] counter = 0;       // 255 counts max
   reg [2:0] count8 = 0;
   reg [2:0] state = 0;
   reg [4:0] count23 = 0;
   reg [5:0] count60 = 0;
   reg [3:0] count16 = 0 ;
   reg [59:0] data;

   localparam IDLE = 0;
   localparam START = 1;
   localparam WAIT = 2;
   localparam SHIFT = 3;
   localparam WAIT2 = 4;
   localparam DONE = 5;
   localparam PROCESS = 1;


   always @(posedge clk) begin
     done <= 0;
     if (enable) begin
       case (state)
        IDLE: begin  // wait for 255 consecutive high [7:0]
               counter <= din ? counter+1 : 0;
               state <= (counter == 255) ? START : IDLE;
               end
        START: begin  // wait for start pulse
                    data <= 0;
                    count23 <= 0; // intialize count8 [2:0]
                    state <= din ? START : WAIT;
               end
        WAIT:  begin  // wait for 1.5  bit period ~ 16 + 7 count = 23
                count23 <= count23 + 1;  // [4:0]
                count60 <= 0;
                state <= (count23 == 21) ? SHIFT : WAIT;
               end
       SHIFT: begin // shift in data
                count60 <= count60 + 1;   // [5:0]
                data <= {din, data[59:1]};
                count16 <= 0;
                state <= (count60 == 58) ? DONE : WAIT2;
               end
        WAIT2: begin // wait 1 bit period or 16 counts  // [3:0]
                count16 <= count16+1;
                state <= (count16 == 15) ? SHIFT : WAIT2;
               end
        DONE:  begin
                dout <= data;
                state <= IDLE;
                done <= 1;
               end
        default: state <= IDLE;
        endcase
      end
    else state <= state;
   end
endmodule
