aboutsummaryrefslogtreecommitdiffstats
path: root/tx/dvi_encoder_top.v
diff options
context:
space:
mode:
Diffstat (limited to 'tx/dvi_encoder_top.v')
-rwxr-xr-xtx/dvi_encoder_top.v311
1 files changed, 311 insertions, 0 deletions
diff --git a/tx/dvi_encoder_top.v b/tx/dvi_encoder_top.v
new file mode 100755
index 0000000..7f3c3d3
--- /dev/null
+++ b/tx/dvi_encoder_top.v
@@ -0,0 +1,311 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Xilinx, Inc. 2009 www.xilinx.com
+//
+// XAPP xyz
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// File name : dvi_encoder.v
+//
+// Description : dvi_encoder
+//
+// Date - revision : April 2009 - 1.0.0
+//
+// 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 © 2009 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
+
+module dvi_encoder_top (
+ input wire pclk, // pixel clock
+ input wire pclkx2, // pixel clock x2
+ input wire pclkx10, // pixel clock x2
+ input wire serdesstrobe, // OSERDES2 serdesstrobe
+ input wire rstin, // reset
+ input wire [7:0] blue_din, // Blue data in
+ input wire [7:0] green_din, // Green data in
+ input wire [7:0] red_din, // Red data in
+ input wire hsync, // hsync data
+ input wire vsync, // vsync data
+ input wire de, // data enable
+ output wire [3:0] TMDS,
+ output wire [3:0] TMDSB,
+ input wire vid_pa,
+ input wire vid_gb,
+ input wire dat_pa,
+ input wire dat_gb,
+ input wire dat_ena,
+ input wire [9:0] dat_din,
+ input wire [3:0] ctl_code,
+ input wire [29:0] bypass_sdata,
+ input wire bypass_ena,
+ output reg byp_error,
+ input wire box_active
+);
+
+ wire [9:0] red ;
+ wire [9:0] green ;
+ wire [9:0] blue ;
+
+ wire [9:0] red_t4 ;
+ wire [9:0] green_t4 ;
+ wire [9:0] blue_t4 ;
+
+ wire [4:0] tmds_data0, tmds_data1, tmds_data2;
+ wire [2:0] tmdsint;
+
+ //
+ // Forward TMDS Clock Using OSERDES2 block
+ //
+ reg [4:0] tmdsclkint = 5'b00000;
+ reg toggle = 1'b0;
+
+ always @ (posedge pclkx2 or posedge rstin) begin
+ if (rstin)
+ toggle <= 1'b0;
+ else
+ toggle <= ~toggle;
+ end
+
+ always @ (posedge pclkx2) begin
+ if (toggle)
+ tmdsclkint <= 5'b11111;
+ else
+ tmdsclkint <= 5'b00000;
+ end
+
+ wire tmdsclk;
+
+ serdes_n_to_1 #(
+ .SF (5))
+ clkout (
+ .iob_data_out (tmdsclk),
+ .ioclk (pclkx10),
+ .serdesstrobe (serdesstrobe),
+ .gclk (pclkx2),
+ .reset (rstin),
+ .datain (tmdsclkint));
+
+ OBUFDS TMDS3 (.I(tmdsclk), .O(TMDS[3]), .OB(TMDSB[3])) ;// clock
+
+ //
+ // Forward TMDS Data: 3 channels
+ //
+ serdes_n_to_1 #(.SF(5)) oserdes0 (
+ .ioclk(pclkx10),
+ .serdesstrobe(serdesstrobe),
+ .reset(rstin),
+ .gclk(pclkx2),
+ .datain(tmds_data0),
+ .iob_data_out(tmdsint[0])) ;
+
+ serdes_n_to_1 #(.SF(5)) oserdes1 (
+ .ioclk(pclkx10),
+ .serdesstrobe(serdesstrobe),
+ .reset(rstin),
+ .gclk(pclkx2),
+ .datain(tmds_data1),
+ .iob_data_out(tmdsint[1])) ;
+
+ serdes_n_to_1 #(.SF(5)) oserdes2 (
+ .ioclk(pclkx10),
+ .serdesstrobe(serdesstrobe),
+ .reset(rstin),
+ .gclk(pclkx2),
+ .datain(tmds_data2),
+ .iob_data_out(tmdsint[2])) ;
+
+ OBUFDS TMDS0 (.I(tmdsint[0]), .O(TMDS[0]), .OB(TMDSB[0])) ;
+ OBUFDS TMDS1 (.I(tmdsint[1]), .O(TMDS[1]), .OB(TMDSB[1])) ;
+ OBUFDS TMDS2 (.I(tmdsint[2]), .O(TMDS[2]), .OB(TMDSB[2])) ;
+
+ encodeb encb (
+ .clkin (pclk),
+ .rstin (rstin),
+ .din (blue_din),
+ .c0 (hsync),
+ .c1 (vsync),
+ .de (de),
+ .dout (blue),
+ .vid_gb (vid_gb)) ;
+
+ encodeg encg (
+ .clkin (pclk),
+ .rstin (rstin),
+ .din (green_din),
+ .c0 (ctl_code[0]), // bit 0
+ .c1 (ctl_code[1]), // bit 1
+ .de (de),
+ .dout (green),
+ .vid_gb (vid_gb)) ;
+
+ encoder encr (
+ .clkin (pclk),
+ .rstin (rstin),
+ .din (red_din),
+ .c0 (ctl_code[2]), // bit 2
+ .c1 (ctl_code[3]), // bit 3
+ .de (de),
+ .dout (red),
+ .vid_gb (vid_gb)) ;
+
+encode_terc4 engb_t4
+ ( .clkin (pclk),
+ .rstin (rstin),
+ .din ( {dat_din[9] | dat_gb, dat_din[8] | dat_gb, vsync, hsync} ),
+ .dout (blue_t4),
+ .dat_gb (1'b0) // gb is considered with sync
+ );
+
+encode_terc4 encg_t4
+ ( .clkin (pclk),
+ .rstin (rstin),
+ .din (dat_din[3:0]),
+ .dout (green_t4),
+ .dat_gb (dat_gb)
+ );
+
+encode_terc4 encr_t4
+ ( .clkin (pclk),
+ .rstin (rstin),
+ .din (dat_din[7:4]),
+ .dout (red_t4),
+ .dat_gb (dat_gb)
+ );
+
+ // pipe alignment
+ reg dat_ena_q, dat_ena_reg, dat_ena_r2;
+ reg dat_gb_q, dat_gb_reg, dat_gb_r2;
+
+ always @(posedge pclk or posedge rstin) begin
+ if( rstin ) begin
+ dat_ena_q <= 1'b0;
+ dat_ena_reg <= 1'b0;
+ dat_ena_r2 <= 1'b0;
+ dat_gb_q <= 1'b0;
+ dat_gb_reg <= 1'b0;
+ dat_gb_r2 <= 1'b0;
+ end else begin
+ dat_ena_q <= dat_ena;
+ dat_ena_reg <= dat_ena_q;
+ dat_ena_r2 <= dat_ena_reg;
+
+ dat_gb_q <= dat_gb;
+ dat_gb_reg <= dat_gb_q;
+ dat_gb_r2 <= dat_gb_reg;
+ end
+ end
+
+ // insert four pipe stages to s_data override
+ reg [29:0] byp_sd1;
+ reg [29:0] byp_sd2;
+ reg [29:0] byp_sd3;
+ reg [29:0] byp_sd4;
+ reg [29:0] byp_sd5;
+ reg [4:0] box_active_q;
+ always @(posedge pclk or posedge rstin) begin
+ if( rstin ) begin
+ byp_sd1 <= 30'b0;
+ byp_sd2 <= 30'b0;
+ byp_sd3 <= 30'b0;
+ byp_sd4 <= 30'b0;
+ byp_sd5 <= 30'b0;
+ end else begin
+ byp_sd1 <= bypass_sdata;
+ byp_sd2 <= byp_sd1;
+ byp_sd3 <= byp_sd2;
+ byp_sd4 <= byp_sd3;
+ byp_sd5 <= byp_sd4;
+
+ box_active_q[4] <= box_active_q[3];
+ box_active_q[3] <= box_active_q[2];
+ box_active_q[2] <= box_active_q[1];
+ box_active_q[1] <= box_active_q[0];
+ box_active_q[0] <= box_active;
+ end // else: !if( rstin )
+ end // always @ (posedge pclk or posedge rstin)
+
+// wire [29:0] s_data_x = (dat_ena_r2 | dat_gb_r2) ?
+// {red_t4[9:5], green_t4[9:5], blue_t4[9:5],
+// red_t4[4:0], green_t4[4:0], blue_t4[4:0]} :
+// {red[9:5], green[9:5], blue[9:5],
+// red[4:0], green[4:0], blue[4:0]};
+
+ // this destroys our ability to bypass sound, but fixes the problem
+ // where HDMI data of Red = 0x55, Green = 0x55, blue = anything
+ // causes the stream to flip into TERC4 mode
+ wire [29:0] s_data_x = {red[9:5], green[9:5], blue[9:5],
+ red[4:0], green[4:0], blue[4:0]};
+
+ // was bypass_ena in here...
+ wire [29:0] s_data = !box_active_q[4] ? byp_sd5 : s_data_x;
+
+ always @(posedge pclk or posedge rstin) begin
+ if( rstin ) begin
+ byp_error <= 1'b0;
+ end else begin
+ byp_error = byp_sd5 != s_data_x;
+ end
+ end
+
+ convert_30to15_fifo pixel2x (
+ .rst (rstin),
+ .clk (pclk),
+ .clkx2 (pclkx2),
+ .datain (s_data),
+ .dataout ({tmds_data2, tmds_data1, tmds_data0}));
+
+endmodule