`timescale 1ns / 1ps
/*
   This file was generated automatically by Alchitry Labs version 1.2.0.
   Do not edit this file directly. Instead edit the original Lucid source.
   This is a temporary file and any changes made to it will be destroyed.
*/

/*
   Parameters:
     PCLK_DIV = 1
     Y_RES = HEIGHT
     X_RES = WIDTH
     Y_FRAME = HEIGHT+30
     X_FRAME = WIDTH+387
*/

module hdmi_encoder #(parameter Y_RES = 720, parameter X_RES = 1280, parameter Y_FRAME = Y_RES+30, parameter X_FRAME = X_RES+387) (
    input clk,
    input rst,
    output reg pclk,
    output reg [3:0] tmds,
    output reg [3:0] tmdsb,
    output reg active,
    output reg [11:0] x,
    output reg [10:0] y,
    input [7:0] red,
    input [7:0] green,
    input [7:0] blue
  );
  
  localparam PCLK_DIV = 1'h1;
  
 
  reg clkfbin;
  
  wire [1-1:0] M_pll_oserdes_CLKOUT0;
  wire [1-1:0] M_pll_oserdes_CLKOUT1;
  wire [1-1:0] M_pll_oserdes_CLKOUT2;
  wire [1-1:0] M_pll_oserdes_CLKOUT3;
  wire [1-1:0] M_pll_oserdes_CLKOUT4;
  wire [1-1:0] M_pll_oserdes_CLKOUT5;
  wire [1-1:0] M_pll_oserdes_CLKFBOUT;
  wire [1-1:0] M_pll_oserdes_LOCKED;
  PLL_BASE #(.CLKIN_PERIOD(10), .CLKFBOUT_MULT(10), .CLKOUT0_DIVIDE(1), .CLKOUT1_DIVIDE(10), .CLKOUT2_DIVIDE(5), .COMPENSATION("SOURCE_SYNCHRONOUS")) pll_oserdes (
    .CLKFBIN(clkfbin),
    .CLKIN(clk),
    .RST(1'h0),
    .CLKOUT0(M_pll_oserdes_CLKOUT0),
    .CLKOUT1(M_pll_oserdes_CLKOUT1),
    .CLKOUT2(M_pll_oserdes_CLKOUT2),
    .CLKOUT3(M_pll_oserdes_CLKOUT3),
    .CLKOUT4(M_pll_oserdes_CLKOUT4),
    .CLKOUT5(M_pll_oserdes_CLKOUT5),
    .CLKFBOUT(M_pll_oserdes_CLKFBOUT),
    .LOCKED(M_pll_oserdes_LOCKED)
  );
  
  wire [1-1:0] M_clkfb_buf_O;
  BUFG clkfb_buf (
    .I(M_pll_oserdes_CLKFBOUT),
    .O(M_clkfb_buf_O)
  );
  
  always @* begin
    clkfbin = M_clkfb_buf_O;
  end
  
  wire [1-1:0] M_pclkx2_buf_O;
  BUFG pclkx2_buf (
    .I(M_pll_oserdes_CLKOUT2),
    .O(M_pclkx2_buf_O)
  );
  
  wire [1-1:0] M_pclk_buf_O;
  BUFG pclk_buf (
    .I(M_pll_oserdes_CLKOUT1),
    .O(M_pclk_buf_O)
  );
  
  wire [1-1:0] M_ioclk_buf_IOCLK;
  wire [1-1:0] M_ioclk_buf_SERDESSTROBE;
  wire [1-1:0] M_ioclk_buf_LOCK;
  BUFPLL #(.DIVIDE(5)) ioclk_buf (
    .PLLIN(M_pll_oserdes_CLKOUT0),
    .GCLK(M_pclkx2_buf_O),
    .LOCKED(M_pll_oserdes_LOCKED),
    .IOCLK(M_ioclk_buf_IOCLK),
    .SERDESSTROBE(M_ioclk_buf_SERDESSTROBE),
    .LOCK(M_ioclk_buf_LOCK)
  );
  
  reg [11:0] M_ctrX_d, M_ctrX_q = 1'h0;
  reg [10:0] M_ctrY_d, M_ctrY_q = 1'h0;
  
  reg hSync;
  reg vSync;
  reg drawArea;
  
  wire [4-1:0] M_dvi_tmds;
  wire [4-1:0] M_dvi_tmdsb;
  dvi_encoder dvi (
    .pclk(M_pclk_buf_O),
    .pclkx2(M_pclkx2_buf_O),
    .pclkx10(M_ioclk_buf_IOCLK),
    .strobe(M_ioclk_buf_SERDESSTROBE),
    .rst(~M_ioclk_buf_LOCK),
    .blue(blue),
    .green(green),
    .red(red),
    .hsync(hSync),
    .vsync(vSync),
    .de(drawArea),
    .tmds(M_dvi_tmds),
    .tmdsb(M_dvi_tmdsb)
  );
  
  always @* begin
    M_ctrY_d = M_ctrY_q;
    M_ctrX_d = M_ctrX_q;
    
    M_ctrX_d = (M_ctrX_q == 13'h0682) ? 1'h0 : M_ctrX_q + 1'h1;
    if (M_ctrX_q == 13'h0682) begin
      M_ctrY_d = (M_ctrY_q == 12'h2ed) ? 1'h0 : M_ctrY_q + 1'h1;
    end
    pclk = M_pclk_buf_O;
    hSync = (M_ctrX_q >= 12'h50a) && (M_ctrX_q < 12'h514);
    vSync = (M_ctrY_q >= 11'h2da) && (M_ctrY_q < 11'h2dc);
    drawArea = (M_ctrX_q < 11'h500) && (M_ctrY_q < 10'h2d0);
    active = drawArea;
    x = M_ctrX_q;
    y = M_ctrY_q;
    tmds = M_dvi_tmds;
    tmdsb = M_dvi_tmdsb;
  end
  
  always @(posedge M_pclk_buf_O) begin
    if (rst == 1'b1) begin
      M_ctrX_q <= 1'h0;
      M_ctrY_q <= 1'h0;
    end else begin
      M_ctrX_q <= M_ctrX_d;
      M_ctrY_q <= M_ctrY_d;
    end
  end
  
endmodule