`timescale 1ns / 1ps

module GammaCorrection_Pipeline #(
    parameter reg [4:0] COLOR_DEPTH   = 8
  ) (
    input wire clk,
    input wire reset,

    input wire in_valid,
    output reg out_valid,

    input wire in_ready,
    output wire out_ready,

    input wire in_hsync,
    output wire out_hsync,

    input wire [COLOR_DEPTH - 1 : 0] in_data[3],

    output reg [COLOR_DEPTH - 1 : 0] out_data[3],

    input wire [7:0] gamma_table[256],
    input wire enable
  );
  reg [7:0] data_cache[3];

  assign out_ready   = (!in_en && state == READ_DATA && !reset) ? 1 : 0;
  assign out_receive = (in_en && state == READ_DATA && !reset) ? 1 : 0;

  always @(posedge clk)
  begin
    if (reset)
    begin
      out_en <= 0;
      out_data[0] <= 0;
      out_data[1] <= 0;
      out_data[2] <= 0;

      data_cache[0] <= 0;
      data_cache[1] <= 0;
      data_cache[2] <= 0;
    end
    else
    begin
      case (state)
        READ_DATA:
        begin
          if (in_en)
          begin
            data_cache[0] <= in_data[0];
            data_cache[1] <= in_data[1];
            data_cache[2] <= in_data[2];
          end
        end

        SEND_DATA:
        begin
          if (in_ready && !in_receive)
          begin
            out_en <= 1;
            if (enable)
            begin
              out_data[0] <= gamma_table[data_cache[0]];
              out_data[1] <= gamma_table[data_cache[1]];
              out_data[2] <= gamma_table[data_cache[2]];
            end
            else
            begin
              out_data[0] <= data_cache[0];
              out_data[1] <= data_cache[1];
              out_data[2] <= data_cache[2];
            end
          end
          else
            out_en <= 0;
        end

        default:
          ;
      endcase
    end
  end


endmodule
