aboutsummaryrefslogtreecommitdiffstats
path: root/tx
diff options
context:
space:
mode:
authorbnewbold <bryan@octopart.com>2012-01-20 19:14:58 -0500
committerbnewbold <bryan@octopart.com>2012-01-20 19:14:58 -0500
commit889a5a5395872eeb3740d5d3281b56c7afa47a6f (patch)
treec0efd6404ffdbdfe7f88a173f0836919efdf0184 /tx
downloadnetv_fpga_hdmi_overlay-889a5a5395872eeb3740d5d3281b56c7afa47a6f.tar.gz
netv_fpga_hdmi_overlay-889a5a5395872eeb3740d5d3281b56c7afa47a6f.zip
initial import from NeTV archive
This repository is simply a mirror of the file fpga/hdmi_overlay_0xD_src.tgz downloaded from http://www.kosagi.com/netv_hardware/ on Jan 19th, 2011. It seems to contain all the verilog and scripts required to build FPGA firmware for the NeTV HDMI device from Chumby/Sutajio Ko-Usagi; see http://www.kosagi.com/blog/ for more information. Licensing is vague; see ip/license.txt
Diffstat (limited to 'tx')
-rwxr-xr-xtx/convert_30to15_fifo.v168
-rwxr-xr-xtx/dvi_encoder_top.v311
-rwxr-xr-xtx/encode.v233
-rwxr-xr-xtx/encode_terc4.v86
-rwxr-xr-xtx/encodeb.v231
-rwxr-xr-xtx/encodeg.v231
-rwxr-xr-xtx/encoder.v231
-rwxr-xr-xtx/gbgen.v106
-rwxr-xr-xtx/serdes_n_to_1.v150
9 files changed, 1747 insertions, 0 deletions
diff --git a/tx/convert_30to15_fifo.v b/tx/convert_30to15_fifo.v
new file mode 100755
index 0000000..8ad8727
--- /dev/null
+++ b/tx/convert_30to15_fifo.v
@@ -0,0 +1,168 @@
+module convert_30to15_fifo(
+ input wire rst, // reset
+ input wire clk, // clock input
+ input wire clkx2, // 2x clock input
+ input wire [29:0] datain, // input data for 2:1 serialisation
+ output wire [14:0] dataout); // 5-bit data out
+
+ ////////////////////////////////////////////////////
+ // Here we instantiate a 16x10 Dual Port RAM
+ // and fill first it with data aligned to
+ // clk domain
+ ////////////////////////////////////////////////////
+ wire [3:0] wa; // RAM read address
+ reg [3:0] wa_d; // RAM read address
+ wire [3:0] ra; // RAM read address
+ reg [3:0] ra_d; // RAM read address
+ wire [29:0] dataint; // RAM output
+
+ parameter ADDR0 = 4'b0000;
+ parameter ADDR1 = 4'b0001;
+ parameter ADDR2 = 4'b0010;
+ parameter ADDR3 = 4'b0011;
+ parameter ADDR4 = 4'b0100;
+ parameter ADDR5 = 4'b0101;
+ parameter ADDR6 = 4'b0110;
+ parameter ADDR7 = 4'b0111;
+ parameter ADDR8 = 4'b1000;
+ parameter ADDR9 = 4'b1001;
+ parameter ADDR10 = 4'b1010;
+ parameter ADDR11 = 4'b1011;
+ parameter ADDR12 = 4'b1100;
+ parameter ADDR13 = 4'b1101;
+ parameter ADDR14 = 4'b1110;
+ parameter ADDR15 = 4'b1111;
+
+ always@(wa) begin
+ case (wa)
+ ADDR0 : wa_d = ADDR1 ;
+ ADDR1 : wa_d = ADDR2 ;
+ ADDR2 : wa_d = ADDR3 ;
+ ADDR3 : wa_d = ADDR4 ;
+ ADDR4 : wa_d = ADDR5 ;
+ ADDR5 : wa_d = ADDR6 ;
+ ADDR6 : wa_d = ADDR7 ;
+ ADDR7 : wa_d = ADDR8 ;
+ ADDR8 : wa_d = ADDR9 ;
+ ADDR9 : wa_d = ADDR10;
+ ADDR10 : wa_d = ADDR11;
+ ADDR11 : wa_d = ADDR12;
+ ADDR12 : wa_d = ADDR13;
+ ADDR13 : wa_d = ADDR14;
+ ADDR14 : wa_d = ADDR15;
+ default : wa_d = ADDR0;
+ endcase
+ end
+
+ FDC fdc_wa0 (.C(clk), .D(wa_d[0]), .CLR(rst), .Q(wa[0]));
+ FDC fdc_wa1 (.C(clk), .D(wa_d[1]), .CLR(rst), .Q(wa[1]));
+ FDC fdc_wa2 (.C(clk), .D(wa_d[2]), .CLR(rst), .Q(wa[2]));
+ FDC fdc_wa3 (.C(clk), .D(wa_d[3]), .CLR(rst), .Q(wa[3]));
+
+ //Dual Port fifo to bridge data from clk to clkx2
+ DRAM16XN #(.data_width(30))
+ fifo_u (
+ .DATA_IN(datain),
+ .ADDRESS(wa),
+ .ADDRESS_DP(ra),
+ .WRITE_EN(1'b1),
+ .CLK(clk),
+ .O_DATA_OUT(),
+ .O_DATA_OUT_DP(dataint));
+
+ /////////////////////////////////////////////////////////////////
+ // Here starts clk2x domain for fifo read out
+ // FIFO read is set to be once every 2 cycles of clk2x in order
+ // to keep up pace with the fifo write speed
+ // Also FIFO read reset is delayed a bit in order to avoid
+ // underflow.
+ /////////////////////////////////////////////////////////////////
+
+ always@(ra) begin
+ case (ra)
+ ADDR0 : ra_d = ADDR1 ;
+ ADDR1 : ra_d = ADDR2 ;
+ ADDR2 : ra_d = ADDR3 ;
+ ADDR3 : ra_d = ADDR4 ;
+ ADDR4 : ra_d = ADDR5 ;
+ ADDR5 : ra_d = ADDR6 ;
+ ADDR6 : ra_d = ADDR7 ;
+ ADDR7 : ra_d = ADDR8 ;
+ ADDR8 : ra_d = ADDR9 ;
+ ADDR9 : ra_d = ADDR10;
+ ADDR10 : ra_d = ADDR11;
+ ADDR11 : ra_d = ADDR12;
+ ADDR12 : ra_d = ADDR13;
+ ADDR13 : ra_d = ADDR14;
+ ADDR14 : ra_d = ADDR15;
+ default : ra_d = ADDR0;
+ endcase
+ end
+
+ wire rstsync, rstsync_q, rstp;
+ (* ASYNC_REG = "TRUE" *) FDP fdp_rst (.C(clkx2), .D(rst), .PRE(rst), .Q(rstsync));
+
+ FD fd_rstsync (.C(clkx2), .D(rstsync), .Q(rstsync_q));
+ FD fd_rstp (.C(clkx2), .D(rstsync_q), .Q(rstp));
+
+ wire sync;
+ FDR sync_gen (.Q (sync), .C (clkx2), .R(rstp), .D(~sync));
+
+ FDRE fdc_ra0 (.C(clkx2), .D(ra_d[0]), .R(rstp), .CE(sync), .Q(ra[0]));
+ FDRE fdc_ra1 (.C(clkx2), .D(ra_d[1]), .R(rstp), .CE(sync), .Q(ra[1]));
+ FDRE fdc_ra2 (.C(clkx2), .D(ra_d[2]), .R(rstp), .CE(sync), .Q(ra[2]));
+ FDRE fdc_ra3 (.C(clkx2), .D(ra_d[3]), .R(rstp), .CE(sync), .Q(ra[3]));
+
+ wire [29:0] db;
+
+ FDE fd_db0 (.C(clkx2), .D(dataint[0]), .CE(sync), .Q(db[0]));
+ FDE fd_db1 (.C(clkx2), .D(dataint[1]), .CE(sync), .Q(db[1]));
+ FDE fd_db2 (.C(clkx2), .D(dataint[2]), .CE(sync), .Q(db[2]));
+ FDE fd_db3 (.C(clkx2), .D(dataint[3]), .CE(sync), .Q(db[3]));
+ FDE fd_db4 (.C(clkx2), .D(dataint[4]), .CE(sync), .Q(db[4]));
+ FDE fd_db5 (.C(clkx2), .D(dataint[5]), .CE(sync), .Q(db[5]));
+ FDE fd_db6 (.C(clkx2), .D(dataint[6]), .CE(sync), .Q(db[6]));
+ FDE fd_db7 (.C(clkx2), .D(dataint[7]), .CE(sync), .Q(db[7]));
+ FDE fd_db8 (.C(clkx2), .D(dataint[8]), .CE(sync), .Q(db[8]));
+ FDE fd_db9 (.C(clkx2), .D(dataint[9]), .CE(sync), .Q(db[9]));
+ FDE fd_db10 (.C(clkx2), .D(dataint[10]), .CE(sync), .Q(db[10]));
+ FDE fd_db11 (.C(clkx2), .D(dataint[11]), .CE(sync), .Q(db[11]));
+ FDE fd_db12 (.C(clkx2), .D(dataint[12]), .CE(sync), .Q(db[12]));
+ FDE fd_db13 (.C(clkx2), .D(dataint[13]), .CE(sync), .Q(db[13]));
+ FDE fd_db14 (.C(clkx2), .D(dataint[14]), .CE(sync), .Q(db[14]));
+ FDE fd_db15 (.C(clkx2), .D(dataint[15]), .CE(sync), .Q(db[15]));
+ FDE fd_db16 (.C(clkx2), .D(dataint[16]), .CE(sync), .Q(db[16]));
+ FDE fd_db17 (.C(clkx2), .D(dataint[17]), .CE(sync), .Q(db[17]));
+ FDE fd_db18 (.C(clkx2), .D(dataint[18]), .CE(sync), .Q(db[18]));
+ FDE fd_db19 (.C(clkx2), .D(dataint[19]), .CE(sync), .Q(db[19]));
+ FDE fd_db20 (.C(clkx2), .D(dataint[20]), .CE(sync), .Q(db[20]));
+ FDE fd_db21 (.C(clkx2), .D(dataint[21]), .CE(sync), .Q(db[21]));
+ FDE fd_db22 (.C(clkx2), .D(dataint[22]), .CE(sync), .Q(db[22]));
+ FDE fd_db23 (.C(clkx2), .D(dataint[23]), .CE(sync), .Q(db[23]));
+ FDE fd_db24 (.C(clkx2), .D(dataint[24]), .CE(sync), .Q(db[24]));
+ FDE fd_db25 (.C(clkx2), .D(dataint[25]), .CE(sync), .Q(db[25]));
+ FDE fd_db26 (.C(clkx2), .D(dataint[26]), .CE(sync), .Q(db[26]));
+ FDE fd_db27 (.C(clkx2), .D(dataint[27]), .CE(sync), .Q(db[27]));
+ FDE fd_db28 (.C(clkx2), .D(dataint[28]), .CE(sync), .Q(db[28]));
+ FDE fd_db29 (.C(clkx2), .D(dataint[29]), .CE(sync), .Q(db[29]));
+
+ wire [14:0] mux;
+ assign mux = (~sync) ? db[14:0] : db[29:15];
+
+ FD fd_out0 (.C(clkx2), .D(mux[0]), .Q(dataout[0]));
+ FD fd_out1 (.C(clkx2), .D(mux[1]), .Q(dataout[1]));
+ FD fd_out2 (.C(clkx2), .D(mux[2]), .Q(dataout[2]));
+ FD fd_out3 (.C(clkx2), .D(mux[3]), .Q(dataout[3]));
+ FD fd_out4 (.C(clkx2), .D(mux[4]), .Q(dataout[4]));
+ FD fd_out5 (.C(clkx2), .D(mux[5]), .Q(dataout[5]));
+ FD fd_out6 (.C(clkx2), .D(mux[6]), .Q(dataout[6]));
+ FD fd_out7 (.C(clkx2), .D(mux[7]), .Q(dataout[7]));
+ FD fd_out8 (.C(clkx2), .D(mux[8]), .Q(dataout[8]));
+ FD fd_out9 (.C(clkx2), .D(mux[9]), .Q(dataout[9]));
+ FD fd_out10 (.C(clkx2), .D(mux[10]), .Q(dataout[10]));
+ FD fd_out11 (.C(clkx2), .D(mux[11]), .Q(dataout[11]));
+ FD fd_out12 (.C(clkx2), .D(mux[12]), .Q(dataout[12]));
+ FD fd_out13 (.C(clkx2), .D(mux[13]), .Q(dataout[13]));
+ FD fd_out14 (.C(clkx2), .D(mux[14]), .Q(dataout[14]));
+
+endmodule
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
diff --git a/tx/encode.v b/tx/encode.v
new file mode 100755
index 0000000..7158abc
--- /dev/null
+++ b/tx/encode.v
@@ -0,0 +1,233 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Xilinx, Inc. 2008 www.xilinx.com
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// File name : encode.v
+//
+// Description : TMDS encoder
+//
+// Date - revision : Jan. 2008 - v 1.0
+//
+// Author : Bob Feng
+//
+// Disclaimer: LIMITED WARRANTY AND DISCLAMER. These designs are
+// provided to you "as is". Xilinx and its licensors make and you
+// receive no warranties or conditions, express, implied,
+// statutory or otherwise, and Xilinx specifically disclaims any
+// implied warranties of merchantability, non-infringement,or
+// fitness for a particular purpose. Xilinx does not warrant that
+// the functions contained in these designs will meet your
+// requirements, or that the operation of these designs will be
+// uninterrupted or error free, or that defects in the Designs
+// will be corrected. Furthermore, Xilinx does not warrantor
+// make any representations regarding use or the results of the
+// 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 for any
+// special, incidental, consequential, or indirect damages
+// arising from the use or operation of the designs or
+// accompanying documentation, however caused and on any theory
+// 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 of the
+// essential purpose of any limited remedies herein.
+//
+// Copyright © 2006 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 ps / 1ps
+
+module encode (
+ input clkin, // pixel clock input
+ input rstin, // async. reset input (active high)
+ input [7:0] din, // data inputs: expect registered
+ input c0, // c0 input
+ input c1, // c1 input
+ input de, // de input
+ output reg [9:0] dout, // data outputs
+ input vid_pa // video preamble encoding select
+);
+
+ ////////////////////////////////////////////////////////////
+ // Counting number of 1s and 0s for each incoming pixel
+ // component. Pipe line the result.
+ // Register Data Input so it matches the pipe lined adder
+ // output
+ ////////////////////////////////////////////////////////////
+ reg [3:0] n1d; //number of 1s in din
+ reg [7:0] din_q;
+
+ always @ (posedge clkin) begin
+ n1d <=#1 din[0] + din[1] + din[2] + din[3] + din[4] + din[5] + din[6] + din[7];
+
+ din_q <=#1 din;
+ end
+
+ ///////////////////////////////////////////////////////
+ // Stage 1: 8 bit -> 9 bit
+ // Refer to DVI 1.0 Specification, page 29, Figure 3-5
+ ///////////////////////////////////////////////////////
+ wire decision1;
+
+ assign decision1 = (n1d > 4'h4) | ((n1d == 4'h4) & (din_q[0] == 1'b0));
+/*
+ reg [8:0] q_m;
+ always @ (posedge clkin) begin
+ q_m[0] <=#1 din_q[0];
+ q_m[1] <=#1 (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^ din_q[1]);
+ q_m[2] <=#1 (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^ din_q[2]);
+ q_m[3] <=#1 (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^ din_q[3]);
+ q_m[4] <=#1 (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^ din_q[4]);
+ q_m[5] <=#1 (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^ din_q[5]);
+ q_m[6] <=#1 (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^ din_q[6]);
+ q_m[7] <=#1 (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^ din_q[7]);
+ q_m[8] <=#1 (decision1) ? 1'b0 : 1'b1;
+ end
+*/
+ wire [8:0] q_m;
+ assign q_m[0] = din_q[0];
+ assign q_m[1] = (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^ din_q[1]);
+ assign q_m[2] = (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^ din_q[2]);
+ assign q_m[3] = (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^ din_q[3]);
+ assign q_m[4] = (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^ din_q[4]);
+ assign q_m[5] = (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^ din_q[5]);
+ assign q_m[6] = (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^ din_q[6]);
+ assign q_m[7] = (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^ din_q[7]);
+ assign q_m[8] = (decision1) ? 1'b0 : 1'b1;
+
+ /////////////////////////////////////////////////////////
+ // Stage 2: 9 bit -> 10 bit
+ // Refer to DVI 1.0 Specification, page 29, Figure 3-5
+ /////////////////////////////////////////////////////////
+ reg [3:0] n1q_m, n0q_m; // number of 1s and 0s for q_m
+ always @ (posedge clkin) begin
+ n1q_m <=#1 q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7];
+ n0q_m <=#1 4'h8 - (q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7]);
+ end
+
+ parameter CTRLTOKEN0 = 10'b1101010100;
+ parameter CTRLTOKEN1 = 10'b0010101011;
+ parameter CTRLTOKEN2 = 10'b0101010100;
+ parameter CTRLTOKEN3 = 10'b1010101011;
+
+ reg [4:0] cnt; //disparity counter, MSB is the sign bit
+ wire decision2, decision3;
+
+ assign decision2 = (cnt == 5'h0) | (n1q_m == n0q_m);
+ /////////////////////////////////////////////////////////////////////////
+ // [(cnt > 0) and (N1q_m > N0q_m)] or [(cnt < 0) and (N0q_m > N1q_m)]
+ /////////////////////////////////////////////////////////////////////////
+ assign decision3 = (~cnt[4] & (n1q_m > n0q_m)) | (cnt[4] & (n0q_m > n1q_m));
+
+ ////////////////////////////////////
+ // pipe line alignment
+ ////////////////////////////////////
+ reg de_q, de_reg;
+ reg c0_q, c1_q;
+ reg c0_reg, c1_reg;
+ reg [8:0] q_m_reg;
+ reg vid_pa_q, vid_pa_reg;
+
+
+ always @ (posedge clkin) begin
+ de_q <=#1 de;
+ de_reg <=#1 de_q;
+
+ c0_q <=#1 c0;
+ c0_reg <=#1 c0_q;
+ c1_q <=#1 c1;
+ c1_reg <=#1 c1_q;
+
+ q_m_reg <=#1 q_m;
+
+ vid_pa_q <=#1 vid_pa;
+ vid_pa_reg <=#1 vid_pa_q;
+ end
+
+ ///////////////////////////////
+ // 10-bit out
+ // disparity counter
+ ///////////////////////////////
+ always @ (posedge clkin or posedge rstin) begin
+ if(rstin) begin
+ dout <= 10'h0;
+ cnt <= 5'h0;
+ end else begin
+ if(vid_pa_reg) begin
+ // video preamble coding
+ dout[9:0] <= DNU; // this code shouldn't be used
+ // branch encode into rgb specific lines, since hdmi spec
+ // puts different code on each
+ // don't make it dynamically selectable because it will add logic
+ // to a critical path. Less maintainable to do it with separate encoders
+ // for each path, but on the other hand it makes the compiler's job easier
+ // to optimize each unit.
+ end else begin
+ if (de_reg) begin
+ if(decision2) begin
+ dout[9] <=#1 ~q_m_reg[8];
+ dout[8] <=#1 q_m_reg[8];
+ dout[7:0] <=#1 (q_m_reg[8]) ? q_m_reg[7:0] : ~q_m_reg[7:0];
+
+ cnt <=#1 (~q_m_reg[8]) ? (cnt + n0q_m - n1q_m) : (cnt + n1q_m - n0q_m);
+ end else begin
+ if(decision3) begin
+ dout[9] <=#1 1'b1;
+ dout[8] <=#1 q_m_reg[8];
+ dout[7:0] <=#1 ~q_m_reg[7:0];
+
+ cnt <=#1 cnt + {q_m_reg[8], 1'b0} + (n0q_m - n1q_m);
+ end else begin
+ dout[9] <=#1 1'b0;
+ dout[8] <=#1 q_m_reg[8];
+ dout[7:0] <=#1 q_m_reg[7:0];
+
+ cnt <=#1 cnt - {~q_m_reg[8], 1'b0} + (n1q_m - n0q_m);
+ end
+ end
+ end else begin
+ case ({c1_reg, c0_reg})
+ 2'b00: dout <=#1 CTRLTOKEN0;
+ 2'b01: dout <=#1 CTRLTOKEN1;
+ 2'b10: dout <=#1 CTRLTOKEN2;
+ default: dout <=#1 CTRLTOKEN3;
+ endcase
+
+ cnt <=#1 5'h0;
+ end // else: !if(de_reg)
+ end // if (vid_pa)
+ end // else: !if(rstin)
+ end // always @ (posedge clkin or posedge rstin)
+
+
+endmodule
diff --git a/tx/encode_terc4.v b/tx/encode_terc4.v
new file mode 100755
index 0000000..e6c0e0e
--- /dev/null
+++ b/tx/encode_terc4.v
@@ -0,0 +1,86 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2011, Andrew "bunnie" Huang
+// All rights reserved.
+//
+// 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 ps / 1ps
+
+module encode_terc4 (
+ input clkin, // pixel clock input
+ input rstin, // async. reset input (active high)
+ input [3:0] din, // data inputs: expect registered
+ output reg [9:0] dout, // data outputs
+ input dat_gb
+);
+
+ reg [3:0] din_q; // extra stages to match pipeline delays
+ reg [9:0] q_m_reg; // extra stages to match pipeline delays
+
+ reg dat_gb_q, dat_gb_reg;
+
+ always @(posedge clkin or posedge rstin) begin
+ if(rstin) begin
+ din_q <= 4'b0;
+ dout <= 10'b0;
+ dat_gb_q <= 1'b0;
+ dat_gb_reg <= 1'b0;
+ end else begin
+ din_q <= din;
+ dat_gb_q <= dat_gb;
+ dat_gb_reg <= dat_gb_q;
+
+ if( dat_gb_reg ) begin
+ dout <= 10'b0100110011;
+ end else begin
+ dout <= q_m_reg;
+ end
+ end // else: !if(rstin)
+ end // always @ (posedge clkin or posedge rstin)
+
+ always @(posedge clkin or posedge rstin) begin
+ if( rstin ) begin
+ q_m_reg[9:0] <= 10'h0;
+ end else begin
+ case ({din_q[3], din_q[2], din_q[1], din_q[0]})
+ 4'b0000: q_m_reg[9:0] <= 10'b1010011100;
+ 4'b0001: q_m_reg[9:0] <= 10'b1001100011;
+ 4'b0010: q_m_reg[9:0] <= 10'b1011100100;
+ 4'b0011: q_m_reg[9:0] <= 10'b1011100010;
+ 4'b0100: q_m_reg[9:0] <= 10'b0101110001;
+ 4'b0101: q_m_reg[9:0] <= 10'b0100011110;
+ 4'b0110: q_m_reg[9:0] <= 10'b0110001110;
+ 4'b0111: q_m_reg[9:0] <= 10'b0100111100;
+ 4'b1000: q_m_reg[9:0] <= 10'b1011001100;
+ 4'b1001: q_m_reg[9:0] <= 10'b0100111001;
+ 4'b1010: q_m_reg[9:0] <= 10'b0110011100;
+ 4'b1011: q_m_reg[9:0] <= 10'b1011000110;
+ 4'b1100: q_m_reg[9:0] <= 10'b1010001110;
+ 4'b1101: q_m_reg[9:0] <= 10'b1001110001;
+ 4'b1110: q_m_reg[9:0] <= 10'b0101100011;
+ 4'b1111: q_m_reg[9:0] <= 10'b1011000011;
+ // no default since all cases are covered in this ROM.
+ endcase // case ({din_q[3], din_q[2], din_q[1], din_q[0]})
+ end // else: !if( rstin )
+ end // always @ (posedge clkin or posedge rstin)
+
+endmodule // encode_terc4
diff --git a/tx/encodeb.v b/tx/encodeb.v
new file mode 100755
index 0000000..8bb4ce6
--- /dev/null
+++ b/tx/encodeb.v
@@ -0,0 +1,231 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Xilinx, Inc. 2008 www.xilinx.com
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// File name : encode.v
+//
+// Description : TMDS encoder
+//
+// Date - revision : Jan. 2008 - v 1.0
+//
+// Author : Bob Feng
+//
+// Disclaimer: LIMITED WARRANTY AND DISCLAMER. These designs are
+// provided to you "as is". Xilinx and its licensors make and you
+// receive no warranties or conditions, express, implied,
+// statutory or otherwise, and Xilinx specifically disclaims any
+// implied warranties of merchantability, non-infringement,or
+// fitness for a particular purpose. Xilinx does not warrant that
+// the functions contained in these designs will meet your
+// requirements, or that the operation of these designs will be
+// uninterrupted or error free, or that defects in the Designs
+// will be corrected. Furthermore, Xilinx does not warrantor
+// make any representations regarding use or the results of the
+// 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 for any
+// special, incidental, consequential, or indirect damages
+// arising from the use or operation of the designs or
+// accompanying documentation, however caused and on any theory
+// 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 of the
+// essential purpose of any limited remedies herein.
+//
+// Copyright © 2006 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 ps / 1ps
+
+module encodeb (
+ input clkin, // pixel clock input
+ input rstin, // async. reset input (active high)
+ input [7:0] din, // data inputs: expect registered
+ input c0, // c0 input
+ input c1, // c1 input
+ input de, // de input
+ output reg [9:0] dout, // data outputs
+ input vid_gb // video preamble encoding select
+);
+
+ ////////////////////////////////////////////////////////////
+ // Counting number of 1s and 0s for each incoming pixel
+ // component. Pipe line the result.
+ // Register Data Input so it matches the pipe lined adder
+ // output
+ ////////////////////////////////////////////////////////////
+ reg [3:0] n1d; //number of 1s in din
+ reg [7:0] din_q;
+
+ always @ (posedge clkin) begin
+ n1d <=#1 din[0] + din[1] + din[2] + din[3] + din[4] + din[5] + din[6] + din[7];
+
+ din_q <=#1 din;
+ end
+
+ ///////////////////////////////////////////////////////
+ // Stage 1: 8 bit -> 9 bit
+ // Refer to DVI 1.0 Specification, page 29, Figure 3-5
+ ///////////////////////////////////////////////////////
+ wire decision1;
+
+ assign decision1 = (n1d > 4'h4) | ((n1d == 4'h4) & (din_q[0] == 1'b0));
+/*
+ reg [8:0] q_m;
+ always @ (posedge clkin) begin
+ q_m[0] <=#1 din_q[0];
+ q_m[1] <=#1 (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^ din_q[1]);
+ q_m[2] <=#1 (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^ din_q[2]);
+ q_m[3] <=#1 (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^ din_q[3]);
+ q_m[4] <=#1 (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^ din_q[4]);
+ q_m[5] <=#1 (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^ din_q[5]);
+ q_m[6] <=#1 (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^ din_q[6]);
+ q_m[7] <=#1 (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^ din_q[7]);
+ q_m[8] <=#1 (decision1) ? 1'b0 : 1'b1;
+ end
+*/
+ wire [8:0] q_m;
+ assign q_m[0] = din_q[0];
+ assign q_m[1] = (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^ din_q[1]);
+ assign q_m[2] = (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^ din_q[2]);
+ assign q_m[3] = (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^ din_q[3]);
+ assign q_m[4] = (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^ din_q[4]);
+ assign q_m[5] = (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^ din_q[5]);
+ assign q_m[6] = (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^ din_q[6]);
+ assign q_m[7] = (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^ din_q[7]);
+ assign q_m[8] = (decision1) ? 1'b0 : 1'b1;
+
+ /////////////////////////////////////////////////////////
+ // Stage 2: 9 bit -> 10 bit
+ // Refer to DVI 1.0 Specification, page 29, Figure 3-5
+ /////////////////////////////////////////////////////////
+ reg [3:0] n1q_m, n0q_m; // number of 1s and 0s for q_m
+ always @ (posedge clkin) begin
+ n1q_m <=#1 q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7];
+ n0q_m <=#1 4'h8 - (q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7]);
+ end
+
+ parameter CTRLTOKEN0 = 10'b1101010100;
+ parameter CTRLTOKEN1 = 10'b0010101011;
+ parameter CTRLTOKEN2 = 10'b0101010100;
+ parameter CTRLTOKEN3 = 10'b1010101011;
+
+ parameter CTLBLUGB = 10'b1011001100;
+ parameter CTLGRNGB = 10'b0100110011;
+ parameter CTLREDGB = 10'b1011001100;
+
+ reg [4:0] cnt; //disparity counter, MSB is the sign bit
+ wire decision2, decision3;
+
+ assign decision2 = (cnt == 5'h0) | (n1q_m == n0q_m);
+ /////////////////////////////////////////////////////////////////////////
+ // [(cnt > 0) and (N1q_m > N0q_m)] or [(cnt < 0) and (N0q_m > N1q_m)]
+ /////////////////////////////////////////////////////////////////////////
+ assign decision3 = (~cnt[4] & (n1q_m > n0q_m)) | (cnt[4] & (n0q_m > n1q_m));
+
+ ////////////////////////////////////
+ // pipe line alignment
+ ////////////////////////////////////
+ reg de_q, de_reg;
+ reg c0_q, c1_q;
+ reg c0_reg, c1_reg;
+ reg [8:0] q_m_reg;
+ reg vid_gb_q, vid_gb_reg;
+
+
+ always @ (posedge clkin) begin
+ de_q <=#1 de;
+ de_reg <=#1 de_q;
+
+ c0_q <=#1 c0;
+ c0_reg <=#1 c0_q;
+ c1_q <=#1 c1;
+ c1_reg <=#1 c1_q;
+
+ q_m_reg <=#1 q_m;
+
+ vid_gb_q <=#1 vid_gb;
+ vid_gb_reg <=#1 vid_gb_q;
+ end
+
+ ///////////////////////////////
+ // 10-bit out
+ // disparity counter
+ ///////////////////////////////
+ always @ (posedge clkin or posedge rstin) begin
+ if(rstin) begin
+ dout <= 10'h0;
+ cnt <= 5'h0;
+ end else begin
+ if(vid_gb_reg) begin
+ // video preamble coding
+ dout[9:0] <= CTLBLUGB;
+ end else begin
+ if (de_reg) begin
+ if(decision2) begin
+ dout[9] <=#1 ~q_m_reg[8];
+ dout[8] <=#1 q_m_reg[8];
+ dout[7:0] <=#1 (q_m_reg[8]) ? q_m_reg[7:0] : ~q_m_reg[7:0];
+
+ cnt <=#1 (~q_m_reg[8]) ? (cnt + n0q_m - n1q_m) : (cnt + n1q_m - n0q_m);
+ end else begin
+ if(decision3) begin
+ dout[9] <=#1 1'b1;
+ dout[8] <=#1 q_m_reg[8];
+ dout[7:0] <=#1 ~q_m_reg[7:0];
+
+ cnt <=#1 cnt + {q_m_reg[8], 1'b0} + (n0q_m - n1q_m);
+ end else begin
+ dout[9] <=#1 1'b0;
+ dout[8] <=#1 q_m_reg[8];
+ dout[7:0] <=#1 q_m_reg[7:0];
+
+ cnt <=#1 cnt - {~q_m_reg[8], 1'b0} + (n1q_m - n0q_m);
+ end
+ end
+ end else begin
+ case ({c1_reg, c0_reg})
+ 2'b00: dout <=#1 CTRLTOKEN0;
+ 2'b01: dout <=#1 CTRLTOKEN1;
+ 2'b10: dout <=#1 CTRLTOKEN2;
+ default: dout <=#1 CTRLTOKEN3;
+ endcase
+
+ cnt <=#1 5'h0;
+ end // else: !if(de_reg)
+ end // if (vid_gb)
+ end // else: !if(rstin)
+ end // always @ (posedge clkin or posedge rstin)
+
+
+endmodule
diff --git a/tx/encodeg.v b/tx/encodeg.v
new file mode 100755
index 0000000..128a07e
--- /dev/null
+++ b/tx/encodeg.v
@@ -0,0 +1,231 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Xilinx, Inc. 2008 www.xilinx.com
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// File name : encode.v
+//
+// Description : TMDS encoder
+//
+// Date - revision : Jan. 2008 - v 1.0
+//
+// Author : Bob Feng
+//
+// Disclaimer: LIMITED WARRANTY AND DISCLAMER. These designs are
+// provided to you "as is". Xilinx and its licensors make and you
+// receive no warranties or conditions, express, implied,
+// statutory or otherwise, and Xilinx specifically disclaims any
+// implied warranties of merchantability, non-infringement,or
+// fitness for a particular purpose. Xilinx does not warrant that
+// the functions contained in these designs will meet your
+// requirements, or that the operation of these designs will be
+// uninterrupted or error free, or that defects in the Designs
+// will be corrected. Furthermore, Xilinx does not warrantor
+// make any representations regarding use or the results of the
+// 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 for any
+// special, incidental, consequential, or indirect damages
+// arising from the use or operation of the designs or
+// accompanying documentation, however caused and on any theory
+// 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 of the
+// essential purpose of any limited remedies herein.
+//
+// Copyright © 2006 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 ps / 1ps
+
+module encodeg (
+ input clkin, // pixel clock input
+ input rstin, // async. reset input (active high)
+ input [7:0] din, // data inputs: expect registered
+ input c0, // c0 input
+ input c1, // c1 input
+ input de, // de input
+ output reg [9:0] dout, // data outputs
+ input vid_gb // video preamble encoding select
+);
+
+ ////////////////////////////////////////////////////////////
+ // Counting number of 1s and 0s for each incoming pixel
+ // component. Pipe line the result.
+ // Register Data Input so it matches the pipe lined adder
+ // output
+ ////////////////////////////////////////////////////////////
+ reg [3:0] n1d; //number of 1s in din
+ reg [7:0] din_q;
+
+ always @ (posedge clkin) begin
+ n1d <=#1 din[0] + din[1] + din[2] + din[3] + din[4] + din[5] + din[6] + din[7];
+
+ din_q <=#1 din;
+ end
+
+ ///////////////////////////////////////////////////////
+ // Stage 1: 8 bit -> 9 bit
+ // Refer to DVI 1.0 Specification, page 29, Figure 3-5
+ ///////////////////////////////////////////////////////
+ wire decision1;
+
+ assign decision1 = (n1d > 4'h4) | ((n1d == 4'h4) & (din_q[0] == 1'b0));
+/*
+ reg [8:0] q_m;
+ always @ (posedge clkin) begin
+ q_m[0] <=#1 din_q[0];
+ q_m[1] <=#1 (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^ din_q[1]);
+ q_m[2] <=#1 (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^ din_q[2]);
+ q_m[3] <=#1 (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^ din_q[3]);
+ q_m[4] <=#1 (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^ din_q[4]);
+ q_m[5] <=#1 (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^ din_q[5]);
+ q_m[6] <=#1 (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^ din_q[6]);
+ q_m[7] <=#1 (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^ din_q[7]);
+ q_m[8] <=#1 (decision1) ? 1'b0 : 1'b1;
+ end
+*/
+ wire [8:0] q_m;
+ assign q_m[0] = din_q[0];
+ assign q_m[1] = (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^ din_q[1]);
+ assign q_m[2] = (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^ din_q[2]);
+ assign q_m[3] = (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^ din_q[3]);
+ assign q_m[4] = (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^ din_q[4]);
+ assign q_m[5] = (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^ din_q[5]);
+ assign q_m[6] = (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^ din_q[6]);
+ assign q_m[7] = (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^ din_q[7]);
+ assign q_m[8] = (decision1) ? 1'b0 : 1'b1;
+
+ /////////////////////////////////////////////////////////
+ // Stage 2: 9 bit -> 10 bit
+ // Refer to DVI 1.0 Specification, page 29, Figure 3-5
+ /////////////////////////////////////////////////////////
+ reg [3:0] n1q_m, n0q_m; // number of 1s and 0s for q_m
+ always @ (posedge clkin) begin
+ n1q_m <=#1 q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7];
+ n0q_m <=#1 4'h8 - (q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7]);
+ end
+
+ parameter CTRLTOKEN0 = 10'b1101010100;
+ parameter CTRLTOKEN1 = 10'b0010101011;
+ parameter CTRLTOKEN2 = 10'b0101010100;
+ parameter CTRLTOKEN3 = 10'b1010101011;
+
+ parameter CTLBLUGB = 10'b1011001100;
+ parameter CTLGRNGB = 10'b0100110011;
+ parameter CTLREDGB = 10'b1011001100;
+
+ reg [4:0] cnt; //disparity counter, MSB is the sign bit
+ wire decision2, decision3;
+
+ assign decision2 = (cnt == 5'h0) | (n1q_m == n0q_m);
+ /////////////////////////////////////////////////////////////////////////
+ // [(cnt > 0) and (N1q_m > N0q_m)] or [(cnt < 0) and (N0q_m > N1q_m)]
+ /////////////////////////////////////////////////////////////////////////
+ assign decision3 = (~cnt[4] & (n1q_m > n0q_m)) | (cnt[4] & (n0q_m > n1q_m));
+
+ ////////////////////////////////////
+ // pipe line alignment
+ ////////////////////////////////////
+ reg de_q, de_reg;
+ reg c0_q, c1_q;
+ reg c0_reg, c1_reg;
+ reg [8:0] q_m_reg;
+ reg vid_gb_q, vid_gb_reg;
+
+
+ always @ (posedge clkin) begin
+ de_q <=#1 de;
+ de_reg <=#1 de_q;
+
+ c0_q <=#1 c0;
+ c0_reg <=#1 c0_q;
+ c1_q <=#1 c1;
+ c1_reg <=#1 c1_q;
+
+ q_m_reg <=#1 q_m;
+
+ vid_gb_q <=#1 vid_gb;
+ vid_gb_reg <=#1 vid_gb_q;
+ end
+
+ ///////////////////////////////
+ // 10-bit out
+ // disparity counter
+ ///////////////////////////////
+ always @ (posedge clkin or posedge rstin) begin
+ if(rstin) begin
+ dout <= 10'h0;
+ cnt <= 5'h0;
+ end else begin
+ if(vid_gb_reg) begin
+ // video preamble coding
+ dout[9:0] <= CTLGRNGB;
+ end else begin
+ if (de_reg) begin
+ if(decision2) begin
+ dout[9] <=#1 ~q_m_reg[8];
+ dout[8] <=#1 q_m_reg[8];
+ dout[7:0] <=#1 (q_m_reg[8]) ? q_m_reg[7:0] : ~q_m_reg[7:0];
+
+ cnt <=#1 (~q_m_reg[8]) ? (cnt + n0q_m - n1q_m) : (cnt + n1q_m - n0q_m);
+ end else begin
+ if(decision3) begin
+ dout[9] <=#1 1'b1;
+ dout[8] <=#1 q_m_reg[8];
+ dout[7:0] <=#1 ~q_m_reg[7:0];
+
+ cnt <=#1 cnt + {q_m_reg[8], 1'b0} + (n0q_m - n1q_m);
+ end else begin
+ dout[9] <=#1 1'b0;
+ dout[8] <=#1 q_m_reg[8];
+ dout[7:0] <=#1 q_m_reg[7:0];
+
+ cnt <=#1 cnt - {~q_m_reg[8], 1'b0} + (n1q_m - n0q_m);
+ end
+ end
+ end else begin
+ case ({c1_reg, c0_reg})
+ 2'b00: dout <=#1 CTRLTOKEN0;
+ 2'b01: dout <=#1 CTRLTOKEN1;
+ 2'b10: dout <=#1 CTRLTOKEN2;
+ default: dout <=#1 CTRLTOKEN3;
+ endcase
+
+ cnt <=#1 5'h0;
+ end // else: !if(de_reg)
+ end // if (vid_gb)
+ end // else: !if(rstin)
+ end // always @ (posedge clkin or posedge rstin)
+
+
+endmodule
diff --git a/tx/encoder.v b/tx/encoder.v
new file mode 100755
index 0000000..cf2f4f5
--- /dev/null
+++ b/tx/encoder.v
@@ -0,0 +1,231 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Xilinx, Inc. 2008 www.xilinx.com
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// File name : encode.v
+//
+// Description : TMDS encoder
+//
+// Date - revision : Jan. 2008 - v 1.0
+//
+// Author : Bob Feng
+//
+// Disclaimer: LIMITED WARRANTY AND DISCLAMER. These designs are
+// provided to you "as is". Xilinx and its licensors make and you
+// receive no warranties or conditions, express, implied,
+// statutory or otherwise, and Xilinx specifically disclaims any
+// implied warranties of merchantability, non-infringement,or
+// fitness for a particular purpose. Xilinx does not warrant that
+// the functions contained in these designs will meet your
+// requirements, or that the operation of these designs will be
+// uninterrupted or error free, or that defects in the Designs
+// will be corrected. Furthermore, Xilinx does not warrantor
+// make any representations regarding use or the results of the
+// 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 for any
+// special, incidental, consequential, or indirect damages
+// arising from the use or operation of the designs or
+// accompanying documentation, however caused and on any theory
+// 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 of the
+// essential purpose of any limited remedies herein.
+//
+// Copyright © 2006 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 ps / 1ps
+
+module encoder (
+ input clkin, // pixel clock input
+ input rstin, // async. reset input (active high)
+ input [7:0] din, // data inputs: expect registered
+ input c0, // c0 input
+ input c1, // c1 input
+ input de, // de input
+ output reg [9:0] dout, // data outputs
+ input vid_gb // video preamble encoding select
+);
+
+ ////////////////////////////////////////////////////////////
+ // Counting number of 1s and 0s for each incoming pixel
+ // component. Pipe line the result.
+ // Register Data Input so it matches the pipe lined adder
+ // output
+ ////////////////////////////////////////////////////////////
+ reg [3:0] n1d; //number of 1s in din
+ reg [7:0] din_q;
+
+ always @ (posedge clkin) begin
+ n1d <=#1 din[0] + din[1] + din[2] + din[3] + din[4] + din[5] + din[6] + din[7];
+
+ din_q <=#1 din;
+ end
+
+ ///////////////////////////////////////////////////////
+ // Stage 1: 8 bit -> 9 bit
+ // Refer to DVI 1.0 Specification, page 29, Figure 3-5
+ ///////////////////////////////////////////////////////
+ wire decision1;
+
+ assign decision1 = (n1d > 4'h4) | ((n1d == 4'h4) & (din_q[0] == 1'b0));
+/*
+ reg [8:0] q_m;
+ always @ (posedge clkin) begin
+ q_m[0] <=#1 din_q[0];
+ q_m[1] <=#1 (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^ din_q[1]);
+ q_m[2] <=#1 (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^ din_q[2]);
+ q_m[3] <=#1 (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^ din_q[3]);
+ q_m[4] <=#1 (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^ din_q[4]);
+ q_m[5] <=#1 (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^ din_q[5]);
+ q_m[6] <=#1 (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^ din_q[6]);
+ q_m[7] <=#1 (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^ din_q[7]);
+ q_m[8] <=#1 (decision1) ? 1'b0 : 1'b1;
+ end
+*/
+ wire [8:0] q_m;
+ assign q_m[0] = din_q[0];
+ assign q_m[1] = (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^ din_q[1]);
+ assign q_m[2] = (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^ din_q[2]);
+ assign q_m[3] = (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^ din_q[3]);
+ assign q_m[4] = (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^ din_q[4]);
+ assign q_m[5] = (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^ din_q[5]);
+ assign q_m[6] = (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^ din_q[6]);
+ assign q_m[7] = (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^ din_q[7]);
+ assign q_m[8] = (decision1) ? 1'b0 : 1'b1;
+
+ /////////////////////////////////////////////////////////
+ // Stage 2: 9 bit -> 10 bit
+ // Refer to DVI 1.0 Specification, page 29, Figure 3-5
+ /////////////////////////////////////////////////////////
+ reg [3:0] n1q_m, n0q_m; // number of 1s and 0s for q_m
+ always @ (posedge clkin) begin
+ n1q_m <=#1 q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7];
+ n0q_m <=#1 4'h8 - (q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7]);
+ end
+
+ parameter CTRLTOKEN0 = 10'b1101010100;
+ parameter CTRLTOKEN1 = 10'b0010101011;
+ parameter CTRLTOKEN2 = 10'b0101010100;
+ parameter CTRLTOKEN3 = 10'b1010101011;
+
+ parameter CTLBLUGB = 10'b1011001100;
+ parameter CTLGRNGB = 10'b0100110011;
+ parameter CTLREDGB = 10'b1011001100;
+
+ reg [4:0] cnt; //disparity counter, MSB is the sign bit
+ wire decision2, decision3;
+
+ assign decision2 = (cnt == 5'h0) | (n1q_m == n0q_m);
+ /////////////////////////////////////////////////////////////////////////
+ // [(cnt > 0) and (N1q_m > N0q_m)] or [(cnt < 0) and (N0q_m > N1q_m)]
+ /////////////////////////////////////////////////////////////////////////
+ assign decision3 = (~cnt[4] & (n1q_m > n0q_m)) | (cnt[4] & (n0q_m > n1q_m));
+
+ ////////////////////////////////////
+ // pipe line alignment
+ ////////////////////////////////////
+ reg de_q, de_reg;
+ reg c0_q, c1_q;
+ reg c0_reg, c1_reg;
+ reg [8:0] q_m_reg;
+ reg vid_gb_q, vid_gb_reg;
+
+
+ always @ (posedge clkin) begin
+ de_q <=#1 de;
+ de_reg <=#1 de_q;
+
+ c0_q <=#1 c0;
+ c0_reg <=#1 c0_q;
+ c1_q <=#1 c1;
+ c1_reg <=#1 c1_q;
+
+ q_m_reg <=#1 q_m;
+
+ vid_gb_q <=#1 vid_gb;
+ vid_gb_reg <=#1 vid_gb_q;
+ end
+
+ ///////////////////////////////
+ // 10-bit out
+ // disparity counter
+ ///////////////////////////////
+ always @ (posedge clkin or posedge rstin) begin
+ if(rstin) begin
+ dout <= 10'h0;
+ cnt <= 5'h0;
+ end else begin
+ if(vid_gb_reg) begin
+ // video preamble coding
+ dout[9:0] <= CTLREDGB;
+ end else begin
+ if (de_reg) begin
+ if(decision2) begin
+ dout[9] <=#1 ~q_m_reg[8];
+ dout[8] <=#1 q_m_reg[8];
+ dout[7:0] <=#1 (q_m_reg[8]) ? q_m_reg[7:0] : ~q_m_reg[7:0];
+
+ cnt <=#1 (~q_m_reg[8]) ? (cnt + n0q_m - n1q_m) : (cnt + n1q_m - n0q_m);
+ end else begin
+ if(decision3) begin
+ dout[9] <=#1 1'b1;
+ dout[8] <=#1 q_m_reg[8];
+ dout[7:0] <=#1 ~q_m_reg[7:0];
+
+ cnt <=#1 cnt + {q_m_reg[8], 1'b0} + (n0q_m - n1q_m);
+ end else begin
+ dout[9] <=#1 1'b0;
+ dout[8] <=#1 q_m_reg[8];
+ dout[7:0] <=#1 q_m_reg[7:0];
+
+ cnt <=#1 cnt - {~q_m_reg[8], 1'b0} + (n1q_m - n0q_m);
+ end
+ end
+ end else begin
+ case ({c1_reg, c0_reg})
+ 2'b00: dout <=#1 CTRLTOKEN0;
+ 2'b01: dout <=#1 CTRLTOKEN1;
+ 2'b10: dout <=#1 CTRLTOKEN2;
+ default: dout <=#1 CTRLTOKEN3;
+ endcase
+
+ cnt <=#1 5'h0;
+ end // else: !if(de_reg)
+ end // if (vid_gb)
+ end // else: !if(rstin)
+ end // always @ (posedge clkin or posedge rstin)
+
+
+endmodule
diff --git a/tx/gbgen.v b/tx/gbgen.v
new file mode 100755
index 0000000..b7f0607
--- /dev/null
+++ b/tx/gbgen.v
@@ -0,0 +1,106 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2011, Andrew "bunnie" Huang
+// All rights reserved.
+//
+// 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+module gbgen (
+ input pclk,
+ input rstin,
+ input vsync,
+ input hsync,
+ input sync_pol,
+ input de,
+
+ output gb,
+ output [3:0] code
+ );
+
+ reg [11:0] hpixel;
+ wire [11:0] papos;
+ reg [11:0] depos;
+
+ reg hsync_v; // active when high
+ reg hsync_v2;
+ reg vsync_v;
+ reg vsync_v2;
+ reg de_d;
+
+ wire hsync_rising;
+ wire vsync_rising;
+
+ wire pa;
+
+ always @(posedge pclk) begin
+ if( rstin ) begin
+ hpixel <= 0;
+ depos <= 0;
+ end else begin
+ if( hsync_rising ) begin
+ hpixel <= 0;
+ end else begin
+ hpixel <= hpixel + 12'b1;
+ end
+
+ if( de && !de_d ) begin // de is rising
+ depos <= hpixel;
+ end else begin
+ depos <= depos;
+ end
+ end // else: !if( rstin )
+ end // always @ (posedge pclk)
+
+ assign papos = depos - 12'd10; // note: decimal 10, not binary 10
+ // 0 1 2 3 4 5 6 7
+ // | | | | | | | |
+ // ct pa gb gb v v v v
+ //
+ // depos = 4
+ // gbpos = 2
+
+ assign gb = (hpixel >= (depos - 12'd2)) && (hpixel < depos);
+ assign pa = (hpixel >= papos) && (hpixel < depos);
+
+ assign code[3:1] = 3'b0; // these never change
+ assign code[0] = pa; // this is the only bit that changes on pre-amble
+
+ always @(posedge pclk or posedge rstin) begin
+ if( rstin ) begin
+ hsync_v <= 0;
+ vsync_v <= 0;
+
+ hsync_v2 <= 0;
+ vsync_v2 <= 0;
+ de_d <= 0;
+ end else begin
+ hsync_v <= hsync ^ !sync_pol;
+ vsync_v <= vsync ^ !sync_pol;
+
+ de_d <= de;
+ hsync_v2 <= hsync_v; // just a delayed version
+ vsync_v2 <= vsync_v;
+ end // else: !if( rstin )
+ end // always @ (posedge pclk or posedge rstin)
+ assign hsync_rising = hsync_v & !hsync_v2;
+ assign vsync_rising = vsync_v & !vsync_v2;
+
+endmodule // gbgen
diff --git a/tx/serdes_n_to_1.v b/tx/serdes_n_to_1.v
new file mode 100755
index 0000000..bc384b6
--- /dev/null
+++ b/tx/serdes_n_to_1.v
@@ -0,0 +1,150 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Xilinx, Inc. 2008 www.xilinx.com
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// File name : serdes_n_to_1.v
+//
+// Description : 1-bit generic n:1 transmitter module
+// Takes in n bits of data and serialises this to 1 bit
+// data is transmitted LSB first
+// 0, 1, 2 ......
+//
+// Date - revision : August 1st 2008 - v 1.0
+//
+// Author : NJS
+//
+// Disclaimer: LIMITED WARRANTY AND DISCLAMER. These designs are
+// provided to you "as is". Xilinx and its licensors make and you
+// receive no warranties or conditions, express, implied,
+// statutory or otherwise, and Xilinx specifically disclaims any
+// implied warranties of merchantability, non-infringement,or
+// fitness for a particular purpose. Xilinx does not warrant that
+// the functions contained in these designs will meet your
+// requirements, or that the operation of these designs will be
+// uninterrupted or error free, or that defects in the Designs
+// will be corrected. Furthermore, Xilinx does not warrantor
+// make any representations regarding use or the results of the
+// 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 for any
+// special, incidental, consequential, or indirect damages
+// arising from the use or operation of the designs or
+// accompanying documentation, however caused and on any theory
+// 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 of the
+// essential purpose of any limited remedies herein.
+//
+// Copyright © 2008 Xilinx, Inc.
+// All rights reserved
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+
+`timescale 1ps/1ps
+
+module serdes_n_to_1 (ioclk, serdesstrobe, reset, gclk, datain, iob_data_out) ;
+
+parameter integer SF = 8 ; // Parameter to set the serdes factor 1..8
+
+input ioclk ; // IO Clock network
+input serdesstrobe ; // Parallel data capture strobe
+input reset ; // Reset
+input gclk ; // Global clock
+input [SF-1 : 0] datain ; // Data for output
+output iob_data_out ; // output data
+
+wire cascade_di ; //
+wire cascade_do ; //
+wire cascade_ti ; //
+wire cascade_to ; //
+wire [8:0] mdatain ; //
+
+genvar i ; // Pad out the input data bus with 0's to 8 bits to avoid errors
+generate
+for (i = 0 ; i <= (SF - 1) ; i = i + 1)
+begin : loop0
+assign mdatain[i] = datain[i] ;
+end
+endgenerate
+generate
+for (i = (SF) ; i <= 8 ; i = i + 1)
+begin : loop1
+assign mdatain[i] = 1'b0 ;
+end
+endgenerate
+
+OSERDES2 #(
+ .DATA_WIDTH (SF), // SERDES word width. This should match the setting is BUFPLL
+ .DATA_RATE_OQ ("SDR"), // <SDR>, DDR
+ .DATA_RATE_OT ("SDR"), // <SDR>, DDR
+ .SERDES_MODE ("MASTER"), // <DEFAULT>, MASTER, SLAVE
+ .OUTPUT_MODE ("DIFFERENTIAL"))
+oserdes_m (
+ .OQ (iob_data_out),
+ .OCE (1'b1),
+ .CLK0 (ioclk),
+ .CLK1 (1'b0),
+ .IOCE (serdesstrobe),
+ .RST (reset),
+ .CLKDIV (gclk),
+ .D4 (mdatain[7]),
+ .D3 (mdatain[6]),
+ .D2 (mdatain[5]),
+ .D1 (mdatain[4]),
+ .TQ (),
+ .T1 (1'b0),
+ .T2 (1'b0),
+ .T3 (1'b0),
+ .T4 (1'b0),
+ .TRAIN (1'b0),
+ .TCE (1'b1),
+ .SHIFTIN1 (1'b1), // Dummy input in Master
+ .SHIFTIN2 (1'b1), // Dummy input in Master
+ .SHIFTIN3 (cascade_do), // Cascade output D data from slave
+ .SHIFTIN4 (cascade_to), // Cascade output T data from slave
+ .SHIFTOUT1 (cascade_di), // Cascade input D data to slave
+ .SHIFTOUT2 (cascade_ti), // Cascade input T data to slave
+ .SHIFTOUT3 (), // Dummy output in Master
+ .SHIFTOUT4 ()) ; // Dummy output in Master
+
+OSERDES2 #(
+ .DATA_WIDTH (SF), // SERDES word width. This should match the setting is BUFPLL
+ .DATA_RATE_OQ ("SDR"), // <SDR>, DDR
+ .DATA_RATE_OT ("SDR"), // <SDR>, DDR
+ .SERDES_MODE ("SLAVE"), // <DEFAULT>, MASTER, SLAVE
+ .OUTPUT_MODE ("DIFFERENTIAL"))
+oserdes_s (
+ .OQ (),
+ .OCE (1'b1),
+ .CLK0 (ioclk),
+ .CLK1 (1'b0),
+ .IOCE (serdesstrobe),
+ .RST (reset),
+ .CLKDIV (gclk),
+ .D4 (mdatain[3]),
+ .D3 (mdatain[2]),
+ .D2 (mdatain[1]),
+ .D1 (mdatain[0]),
+ .TQ (),
+ .T1 (1'b0),
+ .T2 (1'b0),
+ .T3 (1'b0),
+ .T4 (1'b0),
+ .TRAIN (1'b0),
+ .TCE (1'b1),
+ .SHIFTIN1 (cascade_di), // Cascade input D from Master
+ .SHIFTIN2 (cascade_ti), // Cascade input T from Master
+ .SHIFTIN3 (1'b1), // Dummy input in Slave
+ .SHIFTIN4 (1'b1), // Dummy input in Slave
+ .SHIFTOUT1 (), // Dummy output in Slave
+ .SHIFTOUT2 (), // Dummy output in Slave
+ .SHIFTOUT3 (cascade_do), // Cascade output D data to Master
+ .SHIFTOUT4 (cascade_to)) ; // Cascade output T data to Master
+
+endmodule