////////////////////////////////////////////////////////////////////////////// // // 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