///////////////////////////////////////////////////////////
// uart_tx.v
// Transmit only 8-bit UART with fixed baud rate
// 
//    - i_valid   - Raise when data is valid on i_data
//                  After accept has been returned valid 
//                  must be driven low before returning 
//                  high to transmit again
//
//    - o_accept  - Raised when data has been transmitted
//
///////////////////////////////////////////////////////////

`timescale 1ns/1ps

module uart_tx(
   input    wire        i_clk,
   input    wire        i_nrst,
   input    wire  [7:0] i_data,
   output   wire        o_tx,
   input    wire        i_valid,
   output   reg         o_accept
);

   parameter   SAMPLE   =  1,
               TX1      =  4'h0,
               TX2      =  4'h1,
               TX3      =  4'h2,
               TX4      =  4'h3,
               TX5      =  4'h4,
               TX6      =  4'h5,
               TX7      =  4'h6,
               TX8      =  4'h7,
               TX_END   =  4'h8,
               TX_IDLE  =  4'h9,
               TX_START =  4'hA;

   reg   [3:0]                   state;
   reg   [$clog2(SAMPLE)-1:0]    count;
 
   assign   full_sample =  (count == SAMPLE  );
   assign   o_tx        =  (state == TX_IDLE )  ?  1'b1                 :
                           (state == TX_START)  ?  1'b0                 :
                           (state == TX_END  )  ?  1'b1                 :
                                                   i_data[state[2:0]]   ;  // TX? 
   
   always@(posedge i_clk or negedge i_nrst) begin
		if(!i_nrst) begin
         state    <= TX_IDLE;  
         count    <= 'b0;
         o_accept <= 1'b0;
		end else begin
         if(full_sample) begin
            count <= 'b0;
         end else begin
            count <= count + 'b1;
         end
	      case(state)
            TX_IDLE:    begin
                           o_accept <= 1'b0;
                           if(i_valid & !o_accept) begin
                              count    <= 'b0;
                              state    <= TX_START;
                           end
                        end
            TX_START:   if(full_sample)   
                           state     <= TX1;
            TX1,
            TX2,
            TX3,
            TX4,
            TX5,
            TX6,
            TX7,
            TX8:        if(full_sample)
                           state    <= state + 4'h1; 
            TX_END:     if(full_sample) begin     
                           state    <= TX_IDLE;
                           o_accept <= 1'b1;
                        end
         endcase
		end
	end
endmodule