aboutsummaryrefslogtreecommitdiffstats
path: root/tx/encoder.v
diff options
context:
space:
mode:
Diffstat (limited to 'tx/encoder.v')
-rwxr-xr-xtx/encoder.v231
1 files changed, 231 insertions, 0 deletions
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