module tx_fifo #(
    parameter WIDTH = 8,  // Taille des données (8 bits)
    parameter DEPTH = 16  // Taille de la FIFO
)(
    input wire clk,
    input wire rst_p,

    // Entrée utilisateur
    input  wire [WIDTH-1:0] tx_data_in,
    input  wire             tx_data_valid,  // Donnée disponible à écrire
    output wire             tx_data_ready,  // FIFO prête à recevoir

    // Sortie vers UART
    output reg  [WIDTH-1:0] tx_data_out,
    input  wire             uart_tx_ready,  // UART demande une donnée
    output reg              fifo_empty,     
    output reg              fifo_full
);

    reg [WIDTH-1:0] fifo_mem [DEPTH-1:0];
    reg [4:0] wr_ptr = 0;
    reg [4:0] rd_ptr = 0;
    reg [4:0] fifo_count = 0;

    always @(posedge clk or posedge rst_p) begin
        tx_data_out <= fifo_mem[rd_ptr];
        if (rst_p) begin
            wr_ptr <= 0;
            rd_ptr <= 0;
            fifo_count <= 0;
            fifo_empty <= 1;
            fifo_full <= 0;
            tx_data_out <= 0;
        end else begin
            // Écriture dans FIFO
            if (tx_data_valid && !fifo_full) begin
                fifo_mem[wr_ptr] <= tx_data_in;
                wr_ptr <= wr_ptr + 1;
                fifo_count <= fifo_count + 1;
            end

            // Lecture depuis FIFO
            if (uart_tx_ready && !fifo_empty) begin
                
                rd_ptr <= rd_ptr + 1;
                fifo_count <= fifo_count - 1;
            end

            // Mise à jour des flags
            fifo_empty <= (fifo_count == 0);
            fifo_full  <= (fifo_count == DEPTH);
        end
    end

    // FIFO est prête à recevoir des données si pas pleine
    assign tx_data_ready = !fifo_full;

endmodule
