////////////////////////////////////////////////////////////////////
//
// KS-10 Processor
//
// brief
//  Double Buffered UART Transmitter
//
// Details
//
// Note
//
// file
//      uart_buftx.vhd
//
// author
//      Rob Doyle - doyle (at) cox (dot) net
//
////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2009, 2010, 2011, 2012 Rob Doyle
//
// This source file may be used and distributed without
// restriction provided that this copyright statement is not
// removed from the file and that any derivative work contains
// the original copyright notice and the associated disclaimer.
//
// This source file is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation;
// version 2.1 of the License.
//
// This source is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General
// Public License along with this source; if not, download it
// from http://www.gnu.org/licenses/lgpl.txt
//
////////////////////////////////////////////////////////////////////

module UART_BUFTX(clk, rst, clkBR, load, data, full, empty, txd);

   input        clk;            // Clock
   input        rst;            // Reset
   input        clkBR;          // Clock Enable from BRG
   input  [7:0] data;           // Transmitter Data
   input        load;		// Load Transmitter
   output       full;		// Buffers is full
   output       empty;		// Buffer is empty
   output       txd;            // Transmitter Serial Data

   //
   // State machine states
   //

   parameter stateEMPTY =  0;   // Empty
   parameter stateUART  =  1;   // Character in UART
   parameter stateBUF   =  2;   // Character buffered and in UART

   //
   // State machine
   //

   wire      txintr;
   reg [0:1] state;
   reg [0:7] txbuf;
   reg [0:7] txdata;
   reg       txload;
   
   always @(posedge clk)
     begin
        if (rst)
          begin
             txdata <= 0;
             txload <= 0;
             state  <= stateEMPTY;
          end
        else
          case (state)
            stateEMPTY:
              if (load)
                begin
                   txload <= 1;
                   txdata <= data;
                   state  <= stateUART;
                end
            stateUART:
              begin
                 if (load & ~txintr)
                   begin
                      txbuf <= data;
                      state <= stateBUF;
                   end
                 if (txintr & ~load)
                   begin
                      txload <= 1;
                      txdata <= txbuf;
                      state  <= stateEMPTY;
                   end
                 if (txintr & load)
                   begin
                      txload <= 1;
                      txbuf  <= data;
                      txdata <= txbuf;
                      state  <= stateUART;
                   end
              end
            stateBUF:
              if (txintr & ~load)
                state <= stateUART;
              else if (txintr & load)
                begin
                   txload <= 1;
                   txbuf  <= data;
                   txdata <= txbuf;
                   state  <= stateBUF;
                end
          endcase
     end
 
   //
   // Unbuffered UART
   //
   
   UART_TX uUART_TX
     (.clk      (clk),
      .rst      (rst),
      .clkBR    (clkBR),
      .data     (txdata),
      .load     (txload),
      .intr     (txintr),
      .txd      (txd)
      );

   //
   // Status
   //
   
   assign full  = (state == stateBUF);
   assign empty = (state == stateEMPTY);
   
endmodule