aboutsummaryrefslogtreecommitdiffstats
path: root/rx/dvi_decoder.v
diff options
context:
space:
mode:
Diffstat (limited to 'rx/dvi_decoder.v')
-rwxr-xr-xrx/dvi_decoder.v634
1 files changed, 634 insertions, 0 deletions
diff --git a/rx/dvi_decoder.v b/rx/dvi_decoder.v
new file mode 100755
index 0000000..1670c58
--- /dev/null
+++ b/rx/dvi_decoder.v
@@ -0,0 +1,634 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Xilinx, Inc. 2010 www.xilinx.com
+//
+// XAPPxxx
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// File name : dvi_decoder.v
+//
+// Description : Spartan-6 DVI decoder top module
+//
+//
+// Author : Bob Feng
+//
+// Disclaimer: LIMITED WARRANTY AND DISCLAMER. These designs are
+// provided to you "as is". Xilinx and its licensors makeand you
+// receive no warranties or conditions, express, implied,
+// statutory or otherwise, and Xilinx specificallydisclaims any
+// implied warranties of merchantability, non-infringement,or
+// fitness for a particular purpose. Xilinx does notwarrant that
+// the functions contained in these designs will meet your
+// requirements, or that the operation of these designswill be
+// uninterrupted or error free, or that defects in theDesigns
+// will be corrected. Furthermore, Xilinx does not warrantor
+// make any representations regarding use or the results ofthe
+// use of the designs in terms of correctness, accuracy,
+// reliability, or otherwise.
+//
+// LIMITATION OF LIABILITY. In no event will Xilinx or its
+// licensors be liable for any loss of data, lost profits,cost
+// or procurement of substitute goods or services, or forany
+// special, incidental, consequential, or indirect damages
+// arising from the use or operation of the designs or
+// accompanying documentation, however caused and on anytheory
+// of liability. This limitation will apply even if Xilinx
+// has been advised of the possibility of such damage. This
+// limitation shall apply not-withstanding the failure ofthe
+// essential purpose of any limited remedies herein.
+//
+// Copyright © 2004 Xilinx, Inc.
+// All rights reserved
+//
+//////////////////////////////////////////////////////////////////////////////
+// Modifications copyright (c) 2011, Andrew "bunnie" Huang
+// All rights reserved as permitted by law.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//////////////////////////////////////////////////////////////////////////////
+`timescale 1 ns / 1ps
+
+// comment out the below line to turn off SS clocking
+// turned off currently because this form causes hdmi locking to fail, suspect lack of
+// phase lock to be the issue
+//`define SS_CLOCKING 1
+
+module dvi_decoder (
+ input wire tmdsclk_p, // tmds clock
+ input wire tmdsclk_n, // tmds clock
+ input wire blue_p, // Blue data in
+ input wire green_p, // Green data in
+ input wire red_p, // Red data in
+ input wire blue_n, // Blue data in
+ input wire green_n, // Green data in
+ input wire red_n, // Red data in
+ input wire exrst, // external reset input, e.g. reset button
+ input wire pllreset, // just reset the PLL only (after LoL)
+
+ output wire reset, // rx reset
+ output wire pclk, // regenerated pixel clock
+ output wire pclkx2, // double rate pixel clock
+ output wire pclkx10, // 10x pixel as IOCLK
+ output wire pllclk0, // send pllclk0 out so it can be fed into a different BUFPLL
+ output wire pllclk1, // PLL x1 output
+ output wire pllclk2, // PLL x2 output
+
+ output wire pll_lckd, // send pll_lckd out so it can be fed into a different BUFPLL
+ output wire serdesstrobe, // BUFPLL serdesstrobe output
+ output wire tmdsclk, // TMDS cable clock
+
+ output reg hsync, // hsync data
+ output reg vsync, // vsync data
+ output reg de, // data enable
+ output wire basic_de, // a DE that strobes even during data guardbands
+
+ output wire blue_vld,
+ output wire green_vld,
+ output wire red_vld,
+ output wire blue_rdy,
+ output wire green_rdy,
+ output wire red_rdy,
+
+ output wire psalgnerr,
+
+ output wire [29:0] sdout, // note this comes 2 pixclk earlier than pix colors
+ output reg [7:0] red, // pixel data out
+ output reg [7:0] green, // pixel data out
+ output reg [7:0] blue, // pixel data out
+
+ output reg encoding, // high when data island is valid
+ output wire hdcp_ena, // OR of data and video encyrption internal signals
+ output wire [3:0] red_di, // red data island
+ output wire [3:0] green_di, // green data island
+ output wire [3:0] blue_di, // blue data island
+ output reg data_gb, // guardbands
+ output reg video_gb,
+ output reg [3:0] ctl_code, // control code
+ output reg cv,
+ output wire line_end // fast-track signal that line ends for HDCP rekey
+ ) ;
+
+ wire g_dgb, b_dgb, r_dgb;
+ wire g_vgb, b_vgb, r_vgb;
+ wire g_cv, b_cv, r_cv;
+
+ wire [3:0] r_t4;
+ wire [3:0] b_t4;
+ wire [3:0] g_t4;
+
+ wire [9:0] sdout_blue;
+ wire [9:0] sdout_green;
+ wire [9:0] sdout_red;
+
+ wire [7:0] red_q1;
+ wire [7:0] blu_q1;
+ wire [7:0] grn_q1;
+
+ reg [7:0] red_q2;
+ reg [7:0] blu_q2;
+ reg [7:0] grn_q2;
+
+ reg de_q1, de_reg;
+ reg hsync_q1, vsync_q1;
+ wire de_q2;
+ wire hsync_q2, vsync_q2;
+ reg cv_q;
+
+ reg data_gb_q, video_gb_q;
+ reg [3:0] ctl_code_q;
+ wire [3:0] ctl_code_wire;
+
+/*
+ assign sdout = {sdout_red[9], sdout_green[9], sdout_blue[9], sdout_red[8], sdout_green[8], sdout_blue[8],
+ sdout_red[7], sdout_green[7], sdout_blue[7], sdout_red[6], sdout_green[6], sdout_blue[6],
+ sdout_red[5], sdout_green[5], sdout_blue[5], sdout_red[4], sdout_green[4], sdout_blue[4],
+ sdout_red[3], sdout_green[3], sdout_blue[3], sdout_red[2], sdout_green[2], sdout_blue[2],
+ sdout_red[1], sdout_green[1], sdout_blue[1], sdout_red[0], sdout_green[0], sdout_blue[0]} ;
+*/
+ parameter INIT = 8'b1 << 0;
+ parameter GOING_T4 = 8'b1 << 1;
+ parameter TERC4 = 8'b1 << 2;
+ parameter LEAVE_T4 = 8'b1 << 3;
+ parameter GOING_VID = 8'b1 << 4;
+ parameter VIDEO = 8'b1 << 5;
+ parameter PREAM_T4 = 8'b1 << 6;
+ parameter PREAM_VID = 8'b1 << 7;
+ parameter nSTATES = 8;
+
+ reg [(nSTATES-1):0] cstate = {{(nSTATES-1){1'b0}},1'b1};
+ reg [(nSTATES-1):0] nstate;
+
+ parameter ENC_TMDS = 1'b0;
+ parameter ENC_TERC4 = 1'b1;
+ parameter HDCP_OFF = 1'b0;
+ parameter HDCP_ON = 1'b1;
+
+// reg encoding;
+ reg encrypting_data;
+ reg encrypting_video;
+
+ assign hdcp_ena = encrypting_data | encrypting_video;
+
+ always @ (posedge pclk or posedge reset) begin
+ if (reset)
+ cstate <= INIT;
+ else
+ cstate <=#1 nstate;
+ end
+
+ always @ (*) begin
+ case (cstate) //synthesis parallel_case full_case
+ //// NOTE NOTE NOTE
+ //// green channel uses same code for video and data gb
+ //// so we can't consider its information in this state machine
+ INIT: begin
+ if( b_vgb & r_vgb & g_vgb ) begin
+// if( b_vgb | r_vgb | g_vgb ) begin
+ nstate = GOING_VID;
+ end else if (ctl_code_wire == 4'b0101) begin
+ // we've found a preamble for data
+ nstate = PREAM_T4;
+ end else if (ctl_code_wire == 4'b0001) begin
+ nstate = PREAM_VID;
+ end else begin
+ nstate = INIT;
+ end
+ end
+ PREAM_T4: begin
+ if( b_vgb & r_vgb & g_vgb ) begin
+// if( b_vgb | r_vgb | g_vgb ) begin
+ nstate = GOING_VID;
+ end else if (r_dgb & g_dgb) begin
+ // data guardband only happens on b/r channels
+ nstate = GOING_T4;
+ end else if (ctl_code_wire == 4'b0101) begin
+ nstate = PREAM_T4;
+ end else begin
+ nstate = INIT;
+ end
+ end
+ GOING_T4: begin
+ // wait till both dgb signals drop
+ nstate = (r_dgb & g_dgb) ? GOING_T4 : TERC4;
+ end
+ TERC4: begin
+ if( b_cv | r_cv | g_cv ) begin
+ nstate = INIT;
+ end else if( b_vgb & r_vgb & g_vgb ) begin
+// end else if( b_vgb | r_vgb | g_vgb ) begin
+ // if we see a video guardband and we think we're in terc4 encoding
+ // it means we missed the end of data guardband; simply re-initialize
+ // the machine so we always recover from bit error drops
+ nstate = GOING_VID;
+ end else if( r_dgb & g_dgb ) begin
+ // otherwise, gracefully leave
+ nstate = LEAVE_T4;
+ end else begin
+ nstate = TERC4;
+ end
+ end // case: TERC4
+ LEAVE_T4: begin
+ // wait till both dgb signals drop
+ nstate = (r_dgb & g_dgb) ? LEAVE_T4 : INIT;
+ end
+ PREAM_VID: begin
+ if( ctl_code_wire == 4'b0001 ) begin
+ nstate = PREAM_VID;
+ end else if( b_vgb & r_vgb & g_vgb ) begin
+// end else if( b_vgb | r_vgb | g_vgb ) begin
+ nstate = GOING_VID;
+ end else begin
+ nstate = INIT;
+ end
+ end
+ GOING_VID: begin
+ nstate = ( b_vgb & r_vgb & g_vgb ) ? GOING_VID : VIDEO;
+// nstate = ( b_vgb | r_vgb | g_vgb ) ? GOING_VID : VIDEO;
+ end
+ VIDEO: begin
+ if( b_cv | r_cv | g_cv ) begin
+// if( b_cv & r_cv & g_cv ) begin
+ nstate = INIT;
+ end else begin
+ nstate = VIDEO;
+ end
+ end
+ endcase // case (cstate)
+ end
+
+ always @ (posedge pclk or posedge reset) begin
+ if( reset ) begin
+ encoding <=#1 ENC_TMDS;
+ encrypting_data <=#1 HDCP_OFF;
+ end else begin
+ case (cstate) // synthesis parallel_case full_case
+ INIT: begin
+ encoding <= #1 ENC_TMDS;
+ encrypting_data <= #1 HDCP_OFF;
+ encrypting_video <= #1 HDCP_OFF;
+ de <= #1 1'b0;
+ end
+ PREAM_T4: begin
+ encoding <= #1 ENC_TMDS;
+ encrypting_data <= #1 HDCP_OFF;
+ encrypting_video <= #1 HDCP_OFF;
+ de <= #1 1'b0;
+ end
+ GOING_T4: begin
+ encoding <= #1 ENC_TERC4;
+ encrypting_data <= #1 HDCP_OFF;
+ encrypting_video <= #1 HDCP_OFF;
+ de <= #1 1'b0;
+ end
+ TERC4: begin
+ encoding <= #1 ENC_TERC4;
+ encrypting_data <= #1 HDCP_ON;
+ encrypting_video <= #1 HDCP_OFF;
+ de <= #1 1'b0;
+ end
+ LEAVE_T4: begin
+ encoding <= #1 ENC_TERC4;
+ encrypting_video <= #1 HDCP_OFF;
+ encrypting_data <= #1 HDCP_OFF;
+ de <= #1 1'b0;
+ end
+ PREAM_VID: begin
+ encoding <= #1 ENC_TMDS;
+ encrypting_data <= #1 HDCP_OFF;
+ encrypting_video <= #1 HDCP_OFF;
+ de <= #1 1'b0;
+ end
+ GOING_VID: begin
+ encoding <= #1 ENC_TMDS;
+ encrypting_data <= #1 HDCP_OFF;
+ encrypting_video <= #1 HDCP_OFF;
+ de <= #1 1'b0;
+ end
+ VIDEO: begin
+ encoding <= #1 ENC_TMDS;
+ encrypting_data <= #1 HDCP_OFF;
+ encrypting_video <= #1 HDCP_ON;
+ de <= #1 1'b1;
+ end
+ endcase // case (cstate)
+ end // else: !if( reset )
+ end // always @ (posedge pclk or posedge reset)
+
+
+ assign sdout = {sdout_red[9:5], sdout_green[9:5], sdout_blue[9:5],
+ sdout_red[4:0], sdout_green[4:0], sdout_blue[4:0]};
+
+ wire de_b, de_g, de_r;
+
+ assign de_q2 = de_b;
+ // to do: modify this against guard bands -- if dgb activates, set a flag to set terc4 coding
+ // until dgb triggers again; include a force-clear if a vgb is encountered
+
+ //wire blue_vld, green_vld, red_vld;
+ //wire blue_rdy, green_rdy, red_rdy;
+
+ wire blue_psalgnerr, green_psalgnerr, red_psalgnerr;
+
+ //
+ // Send TMDS clock to a differential buffer and then a BUFIO2
+ // This is a required path in Spartan-6 feed a PLL CLKIN
+ //
+ wire rxclkint;
+ IBUFDS #(.IOSTANDARD("TMDS_33"), .DIFF_TERM("FALSE")
+ ) ibuf_rxclk (.I(tmdsclk_p), .IB(tmdsclk_n), .O(rxclkint));
+
+ wire rxclk;
+`ifdef SS_CLOCKING
+ wire rxclk_pre_ss; //
+
+ BUFIO2 #(.DIVIDE_BYPASS("TRUE"), .DIVIDE(1))
+ bufio_tmdsclk (.DIVCLK(rxclk_pre_ss), .IOCLK(), .SERDESSTROBE(), .I(rxclkint));
+
+ BUFG tmdsclk_bufg (.I(rxclk), .O(tmdsclk));
+
+ // use spread spectrum clocking to reduce emissions...
+ DCM_CLKGEN #(
+ .DFS_OSCILLATOR_MODE("PHASE_FREQ_LOCK"),
+ .CLKIN_PERIOD ("13.48"),
+ .SPREAD_SPECTRUM ("CENTER_LOW_SPREAD"),
+ .CLKFX_MD_MAX("1.0"),
+ .CLKFX_MULTIPLY (4),
+ .CLKFX_DIVIDE (4) )
+ dcm_fcc_spreads_me_wide (
+ .CLKIN (rxclk_pre_ss),
+ .FREEZEDCM (1'b0),
+// .PROGDATA (progdata_int),
+// .PROGEN (progen_int),
+// .PROGCLK (clk26bufpll),
+// .PROGDONE (progdone),
+// .CLKFX180 (CLKFX180_DCM),
+// .CLKFXDV (CLKFXDV_DCM),
+ // .LOCKED (clkgen_locked),
+ .RST (rx0_reset),
+ .CLKFX (rxclk_ss)
+ );
+ BUFG tmdsclk_bfgss (.I(rxclk_ss), .O(rxclk) ); //
+`else // !`ifdef SS_CLOCKING
+
+ BUFIO2 #(.DIVIDE_BYPASS("TRUE"), .DIVIDE(1))
+ bufio_tmdsclk (.DIVCLK(rxclk), .IOCLK(), .SERDESSTROBE(), .I(rxclkint));
+
+ BUFG tmdsclk_bufg (.I(rxclk), .O(tmdsclk));
+
+`endif // !`ifdef SS_CLOCKING
+
+
+ //
+ // PLL is used to generate three clocks:
+ // 1. pclk: same rate as TMDS clock
+ // 2. pclkx2: double rate of pclk used for 5:10 soft gear box and ISERDES DIVCLK
+ // 3. pclkx10: 10x rate of pclk used as IO clock
+ //
+ wire clkfbin;
+ wire clkfbout;
+ wire clkfbin_fb;
+
+ PLL_BASE # (
+// .CLKIN_PERIOD(10.526315), // 95 MHz
+ .CLKIN_PERIOD(13.481449525), // 74.176 MHz
+ .CLKFBOUT_MULT(10), //set VCO to 10x of CLKIN
+ .CLKOUT0_DIVIDE(1),
+ .CLKOUT1_DIVIDE(10),
+ .CLKOUT2_DIVIDE(5),
+// .COMPENSATION("INTERNAL")
+// .BANDWIDTH("LOW"), // normally not here
+ .COMPENSATION("SOURCE_SYNCHRONOUS")
+ ) PLL_ISERDES (
+ .CLKFBOUT(clkfbout),
+ .CLKOUT0(pllclk0),
+ .CLKOUT1(pllclk1),
+ .CLKOUT2(pllclk2),
+ .CLKOUT3(),
+ .CLKOUT4(),
+ .CLKOUT5(),
+ .LOCKED(pll_lckd),
+ .CLKFBIN(clkfbin_fb),
+ .CLKIN(rxclk),
+ .RST(exrst || pllreset)
+ );
+
+ // feedback to source-synchronize the clock
+ BUFG pclkfbk (.I(clkfbout), .O(clkfbin) );
+ BUFIO2FB pclkfbk_fb (.I(clkfbin), .O(clkfbin_fb) );
+
+ //
+ // Pixel Rate clock buffer
+ //
+ BUFG pclkbufg (.I(pllclk1), .O(pclk));
+
+ //////////////////////////////////////////////////////////////////
+ // 2x pclk is going to be used to drive IOSERDES2 DIVCLK
+ //////////////////////////////////////////////////////////////////
+ BUFG pclkx2bufg (.I(pllclk2), .O(pclkx2));
+
+ //////////////////////////////////////////////////////////////////
+ // 10x pclk is used to drive IOCLK network so a bit rate reference
+ // can be used by IOSERDES2
+ //////////////////////////////////////////////////////////////////
+
+ wire bufpll_lock;
+ BUFPLL #(.DIVIDE(5)) ioclk_buf (.PLLIN(pllclk0), .GCLK(pclkx2), .LOCKED(pll_lckd),
+ .IOCLK(pclkx10), .SERDESSTROBE(serdesstrobe), .LOCK(bufpll_lock));
+
+ assign reset = ~bufpll_lock;
+
+ wire line_end_r;
+ wire line_end_g;
+ wire line_end_b;
+
+ // note instance-specific decode since each channel has its own specific
+ // guardband character.
+ decodeb dec_b (
+ .reset (reset),
+ .pclk (pclk),
+ .pclkx2 (pclkx2),
+ .pclkx10 (pclkx10),
+ .serdesstrobe (serdesstrobe),
+ .din_p (blue_p),
+ .din_n (blue_n),
+ .other_ch0_rdy(green_rdy),
+ .other_ch1_rdy(red_rdy),
+ .other_ch0_vld(green_vld),
+ .other_ch1_vld(red_vld),
+
+ .iamvld (blue_vld),
+ .iamrdy (blue_rdy),
+ .psalgnerr (blue_psalgnerr),
+ .c0 (hsync_q2),
+ .c1 (vsync_q2),
+ .de (de_b),
+ .sdout (sdout_blue),
+ .dout (blu_q1),
+ .dgb (b_dgb),
+ .vgb (b_vgb),
+ .ctl_vld (b_cv),
+ .line_end (line_end_b)) ;
+
+ decodeg dec_g (
+ .reset (reset),
+ .pclk (pclk),
+ .pclkx2 (pclkx2),
+ .pclkx10 (pclkx10),
+ .serdesstrobe (serdesstrobe),
+ .din_p (green_p),
+ .din_n (green_n),
+ .other_ch0_rdy(blue_rdy),
+ .other_ch1_rdy(red_rdy),
+ .other_ch0_vld(blue_vld),
+ .other_ch1_vld(red_vld),
+
+ .iamvld (green_vld),
+ .iamrdy (green_rdy),
+ .psalgnerr (green_psalgnerr),
+ .c0 (ctl_code_wire[0]),
+ .c1 (ctl_code_wire[1]),
+ .de (de_g),
+ .sdout (sdout_green),
+ .dout (grn_q1),
+ .dgb (g_dgb),
+ .vgb (g_vgb),
+ .ctl_vld (g_cv),
+ .line_end (line_end_g)) ;
+
+ decoder dec_r (
+ .reset (reset),
+ .pclk (pclk),
+ .pclkx2 (pclkx2),
+ .pclkx10 (pclkx10),
+ .serdesstrobe (serdesstrobe),
+ .din_p (red_p),
+ .din_n (red_n),
+ .other_ch0_rdy(blue_rdy),
+ .other_ch1_rdy(green_rdy),
+ .other_ch0_vld(blue_vld),
+ .other_ch1_vld(green_vld),
+
+ .iamvld (red_vld),
+ .iamrdy (red_rdy),
+ .psalgnerr (red_psalgnerr),
+ .c0 (ctl_code_wire[2]),
+ .c1 (ctl_code_wire[3]),
+ .de (de_r),
+ .sdout (sdout_red),
+ .dout (red_q1),
+ .dgb (r_dgb),
+ .vgb (r_vgb),
+ .ctl_vld (r_cv),
+ .line_end (line_end_r)) ;
+
+ assign basic_de = de_b | de_r | de_g | b_vgb | r_vgb | g_vgb;
+
+ assign line_end = line_end_g | line_end_r | line_end_b;
+
+ assign psalgnerr = red_psalgnerr | blue_psalgnerr | green_psalgnerr;
+
+ // pipe alignment registers
+ always @(posedge pclk or posedge reset) begin
+ if( reset ) begin
+ red <= 8'b0;
+ red_q2 <= 8'b0;
+ blue <= 8'b0;
+ blu_q2 <= 8'b0;
+ green <= 8'b0;
+ grn_q2 <= 8'b0;
+
+ hsync <= 1'b0;
+ hsync_q1 <= 1'b0;
+
+ vsync <= 1'b0;
+ vsync_q1 <= 1'b0;
+
+ de_reg <= 1'b0;
+ de_q1 <= 1'b0;
+
+ data_gb_q <= 1'b0;
+ data_gb <= 1'b0;
+ video_gb_q <= 1'b0;
+ video_gb <= 1'b0;
+ ctl_code_q <= 4'b0;
+ ctl_code <= 4'b0;
+
+ cv_q <= 1'b0;
+ cv <= 1'b0;
+ end else begin
+ red_q2 <= red_q1;
+ red <= red_q2;
+
+ blu_q2 <= blu_q1;
+ blue <= blu_q2;
+
+ grn_q2 <= grn_q1;
+ green <= grn_q2;
+
+ // reversed the naming convention for the following pipe stages
+ hsync <= hsync_q1;
+ hsync_q1 <= hsync_q2;
+
+ vsync <= vsync_q1;
+ vsync_q1 <= vsync_q2;
+
+ de_reg <= de_q1;
+ de_q1 <= de_q2;
+
+ data_gb_q <= r_dgb & g_vgb; // data guardbands only on red and green channels
+ data_gb <= data_gb_q;
+
+ video_gb_q <= r_vgb & b_vgb & g_vgb;
+ video_gb <= video_gb_q;
+
+ ctl_code_q <= ctl_code_wire;
+ ctl_code <= ctl_code_q;
+
+ cv_q <= b_cv & r_cv & g_cv;
+ cv <= cv_q;
+ end // else: !if( reset )
+ end // always @ (posedge pclk or posedge reset)
+// assign de = de_reg & (encoding == ENC_TMDS);
+
+ decode_terc4 dec_t4_g (
+ .rstin( reset ),
+ .clkin(pclk),
+ .din(sdout_green),
+ .dout(g_t4));
+
+ decode_terc4 dec_t4_r (
+ .rstin( reset ),
+ .clkin(pclk),
+ .din(sdout_red),
+ .dout(r_t4));
+
+ decode_terc4 dec_t4_b (
+ .rstin( reset ),
+ .clkin(pclk),
+ .din(sdout_blue),
+ .dout(b_t4));
+ assign red_di = r_t4;
+ assign green_di = g_t4;
+ assign blue_di = b_t4;
+
+endmodule