From 889a5a5395872eeb3740d5d3281b56c7afa47a6f Mon Sep 17 00:00:00 2001 From: bnewbold Date: Fri, 20 Jan 2012 19:14:58 -0500 Subject: 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 --- tx/convert_30to15_fifo.v | 168 +++++++++++++++++++++++++ tx/dvi_encoder_top.v | 311 +++++++++++++++++++++++++++++++++++++++++++++++ tx/encode.v | 233 +++++++++++++++++++++++++++++++++++ tx/encode_terc4.v | 86 +++++++++++++ tx/encodeb.v | 231 +++++++++++++++++++++++++++++++++++ tx/encodeg.v | 231 +++++++++++++++++++++++++++++++++++ tx/encoder.v | 231 +++++++++++++++++++++++++++++++++++ tx/gbgen.v | 106 ++++++++++++++++ tx/serdes_n_to_1.v | 150 +++++++++++++++++++++++ 9 files changed, 1747 insertions(+) create mode 100755 tx/convert_30to15_fifo.v create mode 100755 tx/dvi_encoder_top.v create mode 100755 tx/encode.v create mode 100755 tx/encode_terc4.v create mode 100755 tx/encodeb.v create mode 100755 tx/encodeg.v create mode 100755 tx/encoder.v create mode 100755 tx/gbgen.v create mode 100755 tx/serdes_n_to_1.v (limited to 'tx') 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"), // , DDR + .DATA_RATE_OT ("SDR"), // , DDR + .SERDES_MODE ("MASTER"), // , 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"), // , DDR + .DATA_RATE_OT ("SDR"), // , DDR + .SERDES_MODE ("SLAVE"), // , 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 -- cgit v1.2.3