summaryrefslogtreecommitdiffstats
path: root/fpga/spartan6/example
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/spartan6/example')
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/common/DRAM16XN.v51
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/common/dcmspi.v142
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/common/debnce.v121
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/common/hdclrbar.v502
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/common/synchro.v93
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/common/timing.v167
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/dvi_demo.v511
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/chnlbond.v170
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/decode.v237
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/dvi_decoder.v242
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/phsaligner.v265
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/serdes_1_to_5_diff_data.v403
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/convert_30to15_fifo.v168
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/dvi_encoder.v103
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/dvi_encoder_top.v172
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/encode.v191
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/serdes_n_to_1.v150
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/vtc_demo.v674
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/ucf/dvi_demo.ucf112
-rw-r--r--fpga/spartan6/example/xapp495/dvi_demo/ucf/vtc_demo.ucf144
-rwxr-xr-xfpga/spartan6/example/xapp495/readme.txt102
21 files changed, 4720 insertions, 0 deletions
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/DRAM16XN.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/DRAM16XN.v
new file mode 100644
index 0000000..656ec8f
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/DRAM16XN.v
@@ -0,0 +1,51 @@
+//
+// Module: DRAM16XN
+//
+// Description: Distributed SelectRAM example
+// Dual Port 16 x N-bit
+//
+// Device: Spartan-3 Family
+//---------------------------------------------------------------------------------------
+
+module DRAM16XN #(parameter data_width = 20)
+ (
+ DATA_IN,
+ ADDRESS,
+ ADDRESS_DP,
+ WRITE_EN,
+ CLK,
+ O_DATA_OUT,
+ O_DATA_OUT_DP);
+
+input [data_width-1:0]DATA_IN;
+input [3:0] ADDRESS;
+input [3:0] ADDRESS_DP;
+input WRITE_EN;
+input CLK;
+
+output [data_width-1:0]O_DATA_OUT_DP;
+output [data_width-1:0]O_DATA_OUT;
+
+genvar i;
+generate
+ for(i = 0 ; i < data_width ; i = i + 1) begin : dram16s
+ RAM16X1D i_RAM16X1D_U(
+ .D(DATA_IN[i]), //insert input signal
+ .WE(WRITE_EN), //insert Write Enable signal
+ .WCLK(CLK), //insert Write Clock signal
+ .A0(ADDRESS[0]), //insert Address 0 signal port SPO
+ .A1(ADDRESS[1]), //insert Address 1 signal port SPO
+ .A2(ADDRESS[2]), //insert Address 2 signal port SPO
+ .A3(ADDRESS[3]), //insert Address 3 signal port SPO
+ .DPRA0(ADDRESS_DP[0]), //insert Address 0 signal dual port DPO
+ .DPRA1(ADDRESS_DP[1]), //insert Address 1 signal dual port DPO
+ .DPRA2(ADDRESS_DP[2]), //insert Address 2 signal dual port DPO
+ .DPRA3(ADDRESS_DP[3]), //insert Address 3 signal dual port DPO
+ .SPO(O_DATA_OUT[i]), //insert output signal SPO
+ .DPO(O_DATA_OUT_DP[i]) //insert output signal DPO
+ );
+ end
+endgenerate
+
+endmodule
+
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/dcmspi.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/dcmspi.v
new file mode 100644
index 0000000..e549f69
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/dcmspi.v
@@ -0,0 +1,142 @@
+/////////////////////////////////////////////////////
+// DCM SPI Controller
+/////////////////////////////////////////////////////
+`timescale 1ns / 1ps
+
+module dcmspi (
+ input RST, //Synchronous Reset
+ input PROGCLK, //SPI clock
+ input PROGDONE, //DCM is ready to take next command
+ input DFSLCKD,
+ input [7:0] M, //DCM M value
+ input [7:0] D, //DCM D value
+ input GO, //Go programme the M and D value into DCM(1 cycle pulse)
+ output reg BUSY,
+ output reg PROGEN, //SlaveSelect,
+ output reg PROGDATA //CommandData
+);
+
+parameter TCQ = 1;
+
+wire [9:0] mval = {M, 1'b1, 1'b1}; //M command: 11,M0-M7
+wire [9:0] dval = {D, 1'b0, 1'b1}; //D command: 10,D0-D7
+
+reg dfslckd_q;
+reg dfslckd_rising;
+always @ (posedge PROGCLK)
+begin
+ dfslckd_q <=#TCQ DFSLCKD;
+ dfslckd_rising <=#TCQ !dfslckd_q & DFSLCKD;
+end
+
+always @ (posedge PROGCLK)
+begin
+ if(RST || (PROGDONE & dfslckd_rising))
+ BUSY <=#TCQ 1'b0;
+ else if (GO)
+ BUSY <=#TCQ 1'b1;
+end
+
+reg [9:0] sndval;
+reg sndm = 1'b0;
+reg sndd = 1'b0;
+
+wire ddone;
+SRL16E VCNT (
+ .Q(ddone), // SRL data output
+ .A0(1'b1), // Select[0] input
+ .A1(1'b0), // Select[1] input
+ .A2(1'b0), // Select[2] input
+ .A3(1'b1), // Select[3] input
+ .CE(1'b1), //clock enable
+ .CLK(PROGCLK), // Clock input
+ .D(GO) // SRL data input
+);
+// The following defparam declaration
+defparam VCNT.INIT = 16'h0;
+
+always @ (posedge PROGCLK)
+begin
+ if(RST || ddone)
+ sndd <=#TCQ 1'b0;
+ else if(GO)
+ sndd <=#TCQ 1'b1;
+end
+
+//V has been sent now it is M's turn
+wire ldm;
+SRL16E DMGAP (
+ .Q(ldm), // SRL data output
+ .A0(1'b0), // Select[0] input
+ .A1(1'b0), // Select[1] input
+ .A2(1'b1), // Select[2] input
+ .A3(1'b0), // Select[3] input
+ .CE(1'b1), //clock enable
+ .CLK(PROGCLK), // Clock input
+ .D(ddone) // SRL data input
+);
+// The following defparam declaration
+defparam DMGAP.INIT = 16'h0;
+
+wire mdone;
+SRL16E MCNT (
+ .Q(mdone), // SRL data output
+ .A0(1'b1), // Select[0] input
+ .A1(1'b0), // Select[1] input
+ .A2(1'b0), // Select[2] input
+ .A3(1'b1), // Select[3] input
+ .CE(1'b1), //clock enable
+ .CLK(PROGCLK), // Clock input
+ .D(ldm) // SRL data input
+);
+// The following defparam declaration
+defparam MCNT.INIT = 16'h0;
+
+always @ (posedge PROGCLK)
+begin
+ if(RST || mdone)
+ sndm <=#TCQ 1'b0;
+ else if(ldm)
+ sndm <=#TCQ 1'b1;
+end
+
+wire gocmd;
+SRL16E GOGAP (
+ .Q(gocmd), // SRL data output
+ .A0(1'b0), // Select[0] input
+ .A1(1'b0), // Select[1] input
+ .A2(1'b1), // Select[2] input
+ .A3(1'b0), // Select[3] input
+ .CE(1'b1), //clock enable
+ .CLK(PROGCLK), // Clock input
+ .D(mdone) // SRL data input
+);
+// The following defparam declaration
+defparam GOGAP.INIT = 16'h0;
+
+always @ (posedge PROGCLK)
+begin
+ if(RST)
+ sndval <=#TCQ 10'h0;
+ else if(GO) //send D first
+ sndval <=#TCQ dval;
+ else if(ldm)
+ sndval <=#TCQ mval;
+ else if(sndm || sndd)
+ sndval <=#TCQ sndval >> 1;
+end
+
+always @ (posedge PROGCLK)
+begin
+ PROGEN <=#TCQ sndd | sndm | gocmd;
+end
+
+always @ (posedge PROGCLK)
+begin
+ if(sndm || sndd)
+ PROGDATA <=#TCQ sndval[0];
+ else
+ PROGDATA <=#TCQ 1'b0;
+end
+
+endmodule
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/debnce.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/debnce.v
new file mode 100644
index 0000000..4377b33
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/debnce.v
@@ -0,0 +1,121 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2006 Xilinx, Inc.
+// This design is confidential and proprietary of Xilinx, All Rights Reserved.
+//////////////////////////////////////////////////////////////////////////////
+// ____ ____
+// / /\/ /
+// /___/ \ / Vendor: Xilinx
+// \ \ \/ Version: 1.0.0
+// \ \ Filename: debnce.v
+// / / Date Created: October 20, 2008
+// /___/ /\ Last Modified: October 20, 2008
+// \ \ / \
+// \___\/\___\
+//
+// Devices: Spartan-3 Generation FPGA
+// Purpose: Switch debouncer: Detecting signal transition and wait for 2^16
+// cycles
+// Contact: bob.feng@xilinx.com
+// Reference: None
+//
+// Revision History:
+// Rev 1.0.0 - (Bob Feng) First created October 20, 2008.
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// LIMITED WARRANTY AND DISCLAIMER. 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 warrant or 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 (c) 2006 Xilinx, Inc.
+// This design is confidential and proprietary of Xilinx, All Rights Reserved.
+//////////////////////////////////////////////////////////////////////////////
+
+`timescale 1 ns / 1 ps
+
+module debnce
+ (
+ input wire sync,
+ input wire clk,
+ output reg debnced = 1'b0
+ );
+
+ //******************************************************************//
+ // Implement debouncing. //
+ //******************************************************************//
+
+ reg [15:0] ctr;
+ reg dly;
+ wire sat;
+
+ reg sync_q;
+ reg transition;
+
+ wire block_out;
+ SRL16E #(.INIT(16'h0)) blockout_0 (
+ .Q(block_out),
+ .A0(1'b1),
+ .A1(1'b1),
+ .A2(1'b1),
+ .A3(1'b1),
+ .CE(1'b1),
+ .CLK(clk),
+ .D(1'b1)
+ );
+
+ always @ (posedge clk) begin
+ sync_q <= sync;
+ transition <= block_out & (sync_q ^ sync);
+ end
+
+ reg cntr_en;
+ always @ (posedge clk) begin
+ if(transition)
+ cntr_en <= 1'b1;
+ else if(sat)
+ cntr_en <= 1'b0;
+ end
+
+
+`ifdef SIMULATION
+ initial begin
+ ctr = 16'b0;
+ end
+
+ parameter SATISFY = 16'hff;
+`else
+ parameter SATISFY = 16'hffff;
+`endif
+
+ assign sat = (ctr == SATISFY);
+
+ always @(posedge clk)
+ begin
+ if(transition)
+ ctr <= 1'b0;
+ else if(cntr_en)
+ ctr <= ctr + 1;
+ end
+
+ always @ (posedge clk) begin
+ debnced <= sat;
+ end
+
+endmodule
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/hdclrbar.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/hdclrbar.v
new file mode 100644
index 0000000..dffacec
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/hdclrbar.v
@@ -0,0 +1,502 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2007 Xilinx, Inc.
+// All Rights Reserved
+//------------------------------------------------------------------------------
+// ____ ____
+// / /\/ /
+// /___/ \ / Vendor: Xilinx
+// \ \ \/ Author: Bob Feng, General Product Division, Xilinx, Inc.
+// \ \ Filename: $RCSfile: hdclrbar.v,v $
+// / / Date Last Modified: $Date: 2010/08/25 00:37:39 $
+// /___/ /\ Date Created: July 26, 2007
+// \ \ / \
+// \___\/\___\
+//
+//------------------------------------------------------------------------------
+/*
+This video pattern generator will generate color bars for the 18 video standards
+currently supported by the SMPTE 292M (HD-SDI) video standard. The color bars
+comply with SMPTE RP-219 standard color bars, as shown below. This module can
+also generate the SMPTE RP-198 HD-SDI checkfield test pattern and 75% color
+bars.
+
+|<-------------------------------------- a ------------------------------------->|
+| |
+| |<----------------------------(3/4)a-------------------------->| |
+| | | |
+| d | c c c c c c c | d |
++--------+--------+--------+--------+--------+--------+--------+--------+--------+ - - - - -
+| | | | | | | | | | ^ ^
+| | | | | | | | | | | |
+| | | | | | | | | | | |
+| | | | | | | | | | | |
+| | | | | | | | | | (7/12)b |
+| 40% | 75% | YELLOW | CYAN | GREEN | MAGENTA| RED | BLUE | 40% | | |
+| GRAY | WHITE | | | | | | | GRAY | | |
+| *1 | | | | | | | | *1 | | b
+| | | | | | | | | | | |
+| | | | | | | | | | | |
+| | | | | | | | | | v |
++--------+--------+--------+--------+--------+--------+--------+--------+--------+ - - - |
+|100%CYAN| *2 | 75% WHITE |100%BLUE| (1/12)b |
++--------+--------+-----------------------------------------------------+--------+ - - - |
+|100%YELO| *3 | Y-RAMP |100% RED| (1/12)b |
++--------+--------+---+-----------------+-------+--+--+--+--+--+--------+--------+ - - - |
+| | | | | | | | | | | | |
+| 15% | 0% | 100% | 0% |BL|BL|BL|BL|BL| 0% | 15% | (3/12)b |
+| GRAY | BLACK | WHITE | BLACK |K-|K |K+|K |K+| BLACK | GRAY | |
+| *4 | | | |2%|0%|2%|0%|4%| | *4 | v
++--------+------------+-----------------+-------+--+--+--+--+--+--------+--------+ - - - - -
+ d (3/2)c 2c (5/6)c c c c c c c d
+ - - - - -
+ 3 3 3 3 3
+
+*1: The block marked *1 is 40% Gray for a default value. This value may
+optionally be set to any other value in accordance with the operational
+requirements of the user.
+
+*2: In the block marked *2, the user may select 75% White, 100% White, +I, or
+-I.
+
+*3: In the block marked *3, the user may select either 0% Black, or +Q. When the
+-I value is selected for the block marked *2, then the +Q signal must be
+selected for the *3 block.
+
+*4: The block marked *4 is 15% Gray for a default value. This value may
+optionally be set to any other value in accordance with the operational
+requirements of the user.
+
+
+
+*/
+module hdcolorbar(
+ input i_clk_74M, //74.25 MHZ pixel clock
+ input i_rst,
+ input baronly, //output only 75% color bar
+ input [1:0] i_format,
+ input [11:0] i_vcnt, //vertical counter from video timing generator
+ input [11:0] i_hcnt, //horizontal counter from video timing generator
+
+ output reg[7:0] o_r,
+ output reg[7:0] o_g,
+ output reg[7:0] o_b
+);
+
+parameter Lvl_100 = 8'd255;
+parameter Lvl_75 = 8'd191;
+parameter Lvl_40 = 8'd102;
+parameter Lvl_15 = 8'd38;
+parameter Lvl_4 = 8'd10;
+parameter Lvl_2 = 8'd5;
+parameter Lvl_0 = 8'd0;
+parameter Lvl_2n = 8'd5;
+parameter I_R = 8'd0; // -I signal
+parameter Q_R = 8'd65;// +Q signal
+parameter I_G = 8'd63;
+parameter Q_G = 8'd0;
+parameter I_B = 8'd105;
+parameter Q_B = 8'd120;
+
+reg [1:0] i_format_sync, i_format_q;
+always @ (posedge i_clk_74M) begin
+ i_format_sync <= i_format_q;
+ i_format_q <= i_format;
+end
+
+wire interlace = i_format_sync[1]; //0-progressive 1-interlace
+wire hdtype = i_format_sync[0]; //0-720 1-1080
+
+///////////////////////////////////////////////////////////
+// There are total 4 vertical and 17 horizontal regions
+///////////////////////////////////////////////////////////
+
+reg [16:0] Hregion;
+reg [3:0] Vregion;
+
+parameter VRGN1 = 4'd0;
+parameter VRGN2 = 4'd1;
+parameter VRGN3 = 4'd2;
+parameter VRGN4 = 4'd3;
+
+parameter HRGN1 = 17'd0;
+parameter HRGN2 = 17'd1;
+parameter HRGN3 = 17'd2;
+parameter HRGN4 = 17'd3;
+parameter HRGN5 = 17'd4;
+parameter HRGN6 = 17'd5;
+parameter HRGN7 = 17'd6;
+parameter HRGN8 = 17'd7;
+parameter HRGN9 = 17'd8;
+parameter HRGN10 = 17'd9;
+parameter HRGN11 = 17'd10;
+parameter HRGN12 = 17'd11;
+parameter HRGN13 = 17'd12;
+parameter HRGN14 = 17'd13;
+parameter HRGN15 = 17'd14;
+parameter HRGN16 = 17'd15;
+parameter HRGN17 = 17'd16;
+
+///////////////////////////////////////////////////////////
+// Define Vertical and Horizontal regions
+///////////////////////////////////////////////////////////
+wire [11:0] vbar1bgn, vbar1bgn2;
+wire [11:0] vbar2bgn, vbar2bgn2;
+wire [11:0] vbar3bgn, vbar3bgn2;
+wire [11:0] vbar4bgn, vbar4bgn2;
+
+wire [11:0] hbar1bgn;
+wire [11:0] hbar2bgn;
+wire [11:0] hbar3bgn;
+wire [11:0] hbar4bgn;
+wire [11:0] hbar5bgn;
+wire [11:0] hbar6bgn;
+wire [11:0] hbar7bgn;
+wire [11:0] hbar8bgn;
+wire [11:0] hbar9bgn;
+wire [11:0] hbar10bgn;
+wire [11:0] hbar11bgn;
+wire [11:0] hbar12bgn;
+wire [11:0] hbar13bgn;
+wire [11:0] hbar14bgn;
+wire [11:0] hbar15bgn;
+wire [11:0] hbar16bgn;
+wire [11:0] hbar17bgn;
+
+/****************************************************************************************************
+ 1080i Vertical Timing:
+
+|<-- 540 Active Lines --->|<-- 23 vblnks --->|<-- 540 Active Lines --->|<-- 22 vblnks -->|
+|_________......__________| |_________......__________| |__......
+| | | | |
+| |______......______| |______......_____|
+^ ^ ^ ^ ^
+0 539 562 1102 1124
+
+VSYNC:
+ _____ _____
+ | | | |
+_____________________________| |______________________________________| |___________
+
+****************************************************************************************************/
+
+///////////////////////////////////////////////////////////////////
+// Here we try to determine vertical ranges
+///////////////////////////////////////////////////////////////////
+assign vbar1bgn = 12'd0;
+assign vbar2bgn = (hdtype) ? ((interlace) ? 12'd315 : 12'd630) : 12'd420;
+assign vbar3bgn = (hdtype) ? ((interlace) ? 12'd360 : 12'd720) : 12'd480;
+assign vbar4bgn = (hdtype) ? ((interlace) ? 12'd405 : 12'd810) : 12'd540;
+
+//This is used only for interlaced second frame
+assign vbar1bgn2 = 12'd563;
+assign vbar2bgn2 = 12'd878;
+assign vbar3bgn2 = 12'd923;
+assign vbar4bgn2 = 12'd968;
+
+///////////////////////////////////////////////////////////////////
+// Here we try to determine horizontal ranges
+///////////////////////////////////////////////////////////////////
+assign hbar1bgn = 12'd0;
+assign hbar2bgn = (hdtype) ? 12'd 240 : 12'd160;
+assign hbar3bgn = (hdtype) ? 12'd 445 : 12'd297;
+assign hbar4bgn = (hdtype) ? 12'd 651 : 12'd434;
+assign hbar5bgn = (hdtype) ? 12'd 857 : 12'd571;
+assign hbar6bgn = (hdtype) ? 12'd 1063 : 12'd709;
+assign hbar7bgn = (hdtype) ? 12'd 1269 : 12'd846;
+assign hbar8bgn = (hdtype) ? 12'd 1475 : 12'd983;
+assign hbar9bgn = (hdtype) ? 12'd 1680 : 12'd1120;
+assign hbar10bgn = (hdtype) ? 12'd 240 : 12'd160;
+assign hbar11bgn = (hdtype) ? 12'd 549 : 12'd366;
+assign hbar12bgn = (hdtype) ? 12'd 960 : 12'd640;
+assign hbar13bgn = (hdtype) ? 12'd 1131 : 12'd754;
+assign hbar14bgn = (hdtype) ? 12'd 1200 : 12'd800;
+assign hbar15bgn = (hdtype) ? 12'd 1268 : 12'd845;
+assign hbar16bgn = (hdtype) ? 12'd 1337 : 12'd891;
+assign hbar17bgn = (hdtype) ? 12'd 1405 : 12'd937;
+
+always @ (posedge i_clk_74M)
+begin
+ if (i_rst) begin
+ Vregion <= 4'h0;
+ end else begin
+ if (baronly)
+ Vregion <= VRGN1;
+ else if(interlace)
+ if (((i_vcnt >= vbar1bgn) && (i_vcnt < vbar2bgn)) ||
+ ((i_vcnt >= vbar1bgn2) && (i_vcnt < vbar2bgn2)))
+ Vregion <= VRGN1;
+ else if (((i_vcnt >= vbar2bgn) && (i_vcnt < vbar3bgn)) ||
+ ((i_vcnt >= vbar2bgn2) && (i_vcnt < vbar3bgn2)))
+ Vregion <= VRGN2;
+ else if (((i_vcnt >= vbar3bgn) && (i_vcnt < vbar4bgn)) ||
+ ((i_vcnt >= vbar3bgn2) && (i_vcnt < vbar4bgn2)))
+ Vregion <= VRGN3;
+ else
+ Vregion <= VRGN4;
+ else
+ if ((i_vcnt >= vbar1bgn) && (i_vcnt < vbar2bgn))
+ Vregion <= VRGN1;
+ else if ((i_vcnt >= vbar2bgn) && (i_vcnt < vbar3bgn))
+ Vregion <= VRGN2;
+ else if ((i_vcnt >= vbar3bgn) && (i_vcnt < vbar4bgn))
+ Vregion <= VRGN3;
+ else
+ Vregion <= VRGN4;
+ end
+end
+
+always @ (posedge i_clk_74M)
+begin
+ if(i_rst) begin
+ Hregion <= 17'h0;
+ end else
+ case (Vregion)
+ VRGN4: begin
+ if((i_hcnt >= hbar1bgn) && (i_hcnt < hbar10bgn))
+ Hregion <= HRGN1;
+ else if((i_hcnt >= hbar10bgn) && (i_hcnt < hbar11bgn))
+ Hregion <= HRGN10;
+ else if((i_hcnt >= hbar11bgn) && (i_hcnt < hbar12bgn))
+ Hregion <= HRGN11;
+ else if((i_hcnt >= hbar12bgn) && (i_hcnt < hbar13bgn))
+ Hregion <= HRGN12;
+ else if((i_hcnt >= hbar13bgn) && (i_hcnt < hbar14bgn))
+ Hregion <= HRGN13;
+ else if((i_hcnt >= hbar14bgn) && (i_hcnt < hbar15bgn))
+ Hregion <= HRGN14;
+ else if((i_hcnt >= hbar15bgn) && (i_hcnt < hbar16bgn))
+ Hregion <= HRGN15;
+ else if((i_hcnt >= hbar16bgn) && (i_hcnt < hbar17bgn))
+ Hregion <= HRGN16;
+ else if((i_hcnt >= hbar17bgn) && (i_hcnt < hbar8bgn))
+ Hregion <= HRGN17;
+ else if((i_hcnt >= hbar8bgn) && (i_hcnt < hbar9bgn))
+ Hregion <= HRGN8;
+ else
+ Hregion <= HRGN9;
+ end
+ default: begin
+ if((i_hcnt >= hbar1bgn) && (i_hcnt < hbar2bgn))
+ Hregion <= HRGN1;
+ else if((i_hcnt >= hbar2bgn) && (i_hcnt < hbar3bgn))
+ Hregion <= HRGN2;
+ else if((i_hcnt >= hbar3bgn) && (i_hcnt < hbar4bgn))
+ Hregion <= HRGN3;
+ else if((i_hcnt >= hbar4bgn) && (i_hcnt < hbar5bgn))
+ Hregion <= HRGN4;
+ else if((i_hcnt >= hbar5bgn) && (i_hcnt < hbar6bgn))
+ Hregion <= HRGN5;
+ else if((i_hcnt >= hbar6bgn) && (i_hcnt < hbar7bgn))
+ Hregion <= HRGN6;
+ else if((i_hcnt >= hbar7bgn) && (i_hcnt < hbar8bgn))
+ Hregion <= HRGN7;
+ else if((i_hcnt >= hbar8bgn) && (i_hcnt < hbar9bgn))
+ Hregion <= HRGN8;
+ else
+ Hregion <= HRGN9;
+ end
+ endcase
+end
+
+always @ (posedge i_clk_74M)
+begin
+ if(i_rst) begin
+ o_r <= Lvl_0;
+ o_g <= Lvl_0;
+ o_b <= Lvl_0;
+ end else
+ case (Vregion)
+ VRGN1: begin
+ case (Hregion)
+ HRGN1: begin
+ o_r <= Lvl_40;
+ o_g <= Lvl_40;
+ o_b <= Lvl_40;
+ end
+ HRGN2: begin
+ o_r <= Lvl_75;
+ o_g <= Lvl_75;
+ o_b <= Lvl_75;
+ end
+ HRGN3: begin
+ o_r <= Lvl_75;
+ o_g <= Lvl_75;
+ o_b <= Lvl_0;
+ end
+ HRGN4: begin
+ o_r <= Lvl_0 ;
+ o_g <= Lvl_75;
+ o_b <= Lvl_75;
+ end
+ HRGN5: begin
+ o_r <= Lvl_0 ;
+ o_g <= Lvl_75;
+ o_b <= Lvl_0;
+ end
+ HRGN6: begin
+ o_r <= Lvl_75;
+ o_g <= Lvl_0;
+ o_b <= Lvl_75;
+ end
+ HRGN7: begin
+ o_r <= Lvl_75;
+ o_g <= Lvl_0;
+ o_b <= Lvl_0;
+ end
+ HRGN8: begin
+ o_r <= Lvl_0;
+ o_g <= Lvl_0;
+ o_b <= Lvl_75;
+ end
+ HRGN9: begin
+ o_r <= Lvl_40;
+ o_g <= Lvl_40;
+ o_b <= Lvl_40;
+ end
+ default: begin
+ o_r <= Lvl_0;
+ o_g <= Lvl_0;
+ o_b <= Lvl_0;
+ end
+ endcase
+ end
+
+ VRGN2: begin
+ case (Hregion)
+ HRGN1: begin //100% Cyan
+ o_r <= Lvl_0;
+ o_g <= Lvl_100;
+ o_b <= Lvl_100;
+ end
+ HRGN2: begin //I
+ o_r <= I_R;
+ o_g <= I_G;
+ o_b <= I_B;
+ end
+ HRGN3, HRGN4, HRGN5, HRGN6, HRGN7, HRGN8: begin //75% White
+ o_r <= Lvl_75;
+ o_g <= Lvl_75;
+ o_b <= Lvl_75;
+ end
+ HRGN9: begin //100% Blue
+ o_r <= Lvl_0;
+ o_g <= Lvl_0;
+ o_b <= Lvl_100;
+ end
+ default: begin
+ o_r <= Lvl_0;
+ o_g <= Lvl_0;
+ o_b <= Lvl_0;
+ end
+ endcase
+ end
+
+ VRGN3: begin
+ case (Hregion)
+ HRGN1: begin //100% Yellow
+ o_r <= Lvl_100;
+ o_g <= Lvl_100;
+ o_b <= Lvl_0;
+ end
+ HRGN2: begin //Q
+ o_r <= Q_R;
+ o_g <= Q_G;
+ o_b <= Q_B;
+ end
+ HRGN3, HRGN4, HRGN5: begin
+ o_r <= Lvl_0;
+ o_g <= Lvl_0;
+ o_b <= Lvl_0;
+ end
+ HRGN6, HRGN7, HRGN8: begin //white ramp
+ o_r <= (o_r == Lvl_100) ? Lvl_100 : o_r + 8'h1;
+ o_g <= (o_g == Lvl_100) ? Lvl_100 : o_g + 8'h1;
+ o_b <= (o_b == Lvl_100) ? Lvl_100 : o_b + 8'h1;
+ end
+ HRGN9: begin //100% RED
+ o_r <= Lvl_100;
+ o_g <= Lvl_0;
+ o_b <= Lvl_0;
+ end
+ default: begin
+ o_r <= Lvl_0;
+ o_g <= Lvl_0;
+ o_b <= Lvl_0;
+ end
+ endcase
+ end
+
+ VRGN4: begin
+ case (Hregion)
+ HRGN1: begin
+ o_r <= Lvl_15;
+ o_g <= Lvl_15;
+ o_b <= Lvl_15;
+ end
+ HRGN10: begin
+ o_r <= Lvl_0;
+ o_g <= Lvl_0;
+ o_b <= Lvl_0;
+ end
+ HRGN11: begin
+ o_r <= Lvl_100;
+ o_g <= Lvl_100;
+ o_b <= Lvl_100;
+ end
+ HRGN12: begin
+ o_r <= Lvl_0;
+ o_g <= Lvl_0;
+ o_b <= Lvl_0;
+ end
+ HRGN13: begin
+ o_r <= Lvl_2n;
+ o_g <= Lvl_2n;
+ o_b <= Lvl_2n;
+ end
+ HRGN14: begin
+ o_r <= Lvl_0;
+ o_g <= Lvl_0;
+ o_b <= Lvl_0;
+ end
+ HRGN15: begin
+ o_r <= Lvl_2;
+ o_g <= Lvl_2;
+ o_b <= Lvl_2;
+ end
+ HRGN16: begin
+ o_r <= Lvl_0;
+ o_g <= Lvl_0;
+ o_b <= Lvl_0;
+ end
+ HRGN17: begin
+ o_r <= Lvl_4;
+ o_g <= Lvl_4;
+ o_b <= Lvl_4;
+ end
+ HRGN8: begin
+ o_r <= Lvl_0;
+ o_g <= Lvl_0;
+ o_b <= Lvl_0;
+ end
+ HRGN9: begin
+ o_r <= Lvl_15;
+ o_g <= Lvl_15;
+ o_b <= Lvl_15;
+ end
+ default: begin
+ o_r <= Lvl_0;
+ o_g <= Lvl_0;
+ o_b <= Lvl_0;
+ end
+ endcase
+ end
+
+ default: begin
+ o_r <= Lvl_0;
+ o_g <= Lvl_0;
+ o_b <= Lvl_0;
+ end
+ endcase
+end
+
+endmodule
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/synchro.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/synchro.v
new file mode 100644
index 0000000..e654b14
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/synchro.v
@@ -0,0 +1,93 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2006 Xilinx, Inc.
+// This design is confidential and proprietary of Xilinx, All Rights Reserved.
+//////////////////////////////////////////////////////////////////////////////
+// ____ ____
+// / /\/ /
+// /___/ \ / Vendor: Xilinx
+// \ \ \/ Version: 1.0.0
+// \ \ Filename: synchro.v
+// / / Date Created: December 25, 2006
+// /___/ /\ Last Modified: December 25, 2006
+// \ \ / \
+// \___\/\___\
+//
+// Devices: Spartan-3 Generation FPGA
+// Purpose: Signal synchronizer, for async inputs
+// Contact: crabill@xilinx.com
+// Reference: None
+//
+// Revision History:
+// Rev 1.0.0 - (crabill) First created December 25, 2006.
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// LIMITED WARRANTY AND DISCLAIMER. 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 warrant or 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 (c) 2006 Xilinx, Inc.
+// This design is confidential and proprietary of Xilinx, All Rights Reserved.
+//////////////////////////////////////////////////////////////////////////////
+
+`timescale 1 ns / 1 ps
+
+module synchro
+ #(
+ parameter INITIALIZE = "LOGIC0"
+ )
+
+ (
+ input wire async,
+ input wire clk,
+ output wire sync
+ );
+
+ //******************************************************************//
+ // Synchronizer. //
+ //******************************************************************//
+
+ wire temp;
+
+ generate
+ if (INITIALIZE == "LOGIC1")
+ begin : use_fdp
+ FDP fda (.Q(temp),.D(async),.C(clk),.PRE(1'b0));
+ FDP fdb (.Q(sync),.D(temp),.C(clk),.PRE(1'b0));
+ end
+ else
+ begin : use_fdc
+ FDC fda (.Q(temp),.D(async),.C(clk),.CLR(1'b0));
+ FDC fdb (.Q(sync),.D(temp),.C(clk),.CLR(1'b0));
+ end
+ endgenerate
+
+ // synthesis attribute ASYNC_REG of fda is "TRUE";
+ // synthesis attribute ASYNC_REG of fdb is "TRUE";
+ // synthesis attribute HU_SET of fda is "SYNC";
+ // synthesis attribute HU_SET of fdb is "SYNC";
+ // synthesis attribute RLOC of fda is "X0Y0";
+ // synthesis attribute RLOC of fdb is "X0Y0";
+
+ //******************************************************************//
+ // //
+ //******************************************************************//
+
+endmodule \ No newline at end of file
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/timing.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/timing.v
new file mode 100644
index 0000000..60a4f69
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/common/timing.v
@@ -0,0 +1,167 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2006 Xilinx, Inc.
+// This design is confidential and proprietary of Xilinx, All Rights Reserved.
+//////////////////////////////////////////////////////////////////////////////
+// ____ ____
+// / /\/ /
+// /___/ \ / Vendor: Xilinx
+// \ \ \/ Version: 1.0.0
+// \ \ Filename: timing.v
+// / / Date Created: December 25, 2006
+// /___/ /\ Last Modified: December 25, 2006
+// \ \ / \
+// \___\/\___\
+//
+// Devices: Spartan-3 Generation FPGA
+// Purpose: Programmable video timing generation circuit
+// Contact: crabill@xilinx.com
+// Reference: None
+//
+// Revision History:
+// Rev 1.0.0 - (crabill) First created December 25, 2006.
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// LIMITED WARRANTY AND DISCLAIMER. 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 warrant or 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 (c) 2006 Xilinx, Inc.
+// This design is confidential and proprietary of Xilinx, All Rights Reserved.
+//////////////////////////////////////////////////////////////////////////////
+
+`timescale 1 ns / 1 ps
+
+module timing
+ (
+ input wire [10:0] tc_hsblnk,
+ input wire [10:0] tc_hssync,
+ input wire [10:0] tc_hesync,
+ input wire [10:0] tc_heblnk,
+
+ output wire [10:0] hcount,
+ output wire hsync,
+ output wire hblnk,
+
+ input wire [10:0] tc_vsblnk,
+ input wire [10:0] tc_vssync,
+ input wire [10:0] tc_vesync,
+ input wire [10:0] tc_veblnk,
+
+ output wire [10:0] vcount,
+ output wire vsync,
+ output wire vblnk,
+
+ input wire restart,
+ input wire clk
+ );
+
+ //******************************************************************//
+ // This logic describes a 11-bit horizontal position counter. //
+ //******************************************************************//
+
+ reg [10:0] hpos_cnt = 0;
+ wire hpos_clr;
+ wire hpos_ena;
+
+ always @(posedge clk)
+ begin : hcounter
+ if (hpos_clr) hpos_cnt <= 11'b000_0000_0000;
+ else if (hpos_ena) hpos_cnt <= hpos_cnt + 11'b000_0000_0001;
+ end
+
+ //******************************************************************//
+ // This logic describes a 11-bit vertical position counter. //
+ //******************************************************************//
+
+ reg [10:0] vpos_cnt = 0;
+ wire vpos_clr;
+ wire vpos_ena;
+
+ always @(posedge clk)
+ begin : vcounter
+ if (vpos_clr) vpos_cnt <= 11'b000_0000_0000;
+ else if (vpos_ena) vpos_cnt <= vpos_cnt + 11'b000_0000_0001;
+ end
+
+ //******************************************************************//
+ // This logic describes the position counter control. Counters are //
+ // reset when they reach the total count and the counter is then //
+ // enabled to advance. Use of GTE operator ensures dynamic changes //
+ // to display timing parameters do not allow counters to run away. //
+ //******************************************************************//
+
+ assign hpos_ena = 1'b1;
+ assign hpos_clr = ((hpos_cnt >= tc_heblnk) && hpos_ena ) || restart;
+
+ assign vpos_ena = hpos_clr;
+ assign vpos_clr = ((vpos_cnt >= tc_veblnk) && vpos_ena ) || restart;
+
+ //******************************************************************//
+ // This is the logic for the horizontal outputs. Active video is //
+ // always started when the horizontal count is zero. Example: //
+ // //
+ // tc_hsblnk = 03 //
+ // tc_hssync = 07 //
+ // tc_hesync = 11 //
+ // tc_heblnk = 15 (htotal) //
+ // //
+ // hcount 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 //
+ // hsync ________________________------------____________ //
+ // hblnk ____________------------------------------------ //
+ // //
+ // hsync time = (tc_hesync - tc_hssync) pixels //
+ // hblnk time = (tc_heblnk - tc_hsblnk) pixels //
+ // active time = (tc_hsblnk + 1) pixels //
+ // //
+ //******************************************************************//
+
+ assign hcount = hpos_cnt;
+ assign hblnk = (hcount > tc_hsblnk);
+ assign hsync = (hcount > tc_hssync) && (hcount <= tc_hesync);
+
+ //******************************************************************//
+ // This is the logic for the vertical outputs. Active video is //
+ // always started when the vertical count is zero. Example: //
+ // //
+ // tc_vsblnk = 03 //
+ // tc_vssync = 07 //
+ // tc_vesync = 11 //
+ // tc_veblnk = 15 (vtotal) //
+ // //
+ // vcount 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 //
+ // vsync ________________________------------____________ //
+ // vblnk ____________------------------------------------ //
+ // //
+ // vsync time = (tc_vesync - tc_vssync) lines //
+ // vblnk time = (tc_veblnk - tc_vsblnk) lines //
+ // active time = (tc_vsblnk + 1) lines //
+ // //
+ //******************************************************************//
+
+ assign vcount = vpos_cnt;
+ assign vblnk = (vcount > tc_vsblnk);
+ assign vsync = (vcount > tc_vssync) && (vcount <= tc_vesync);
+
+ //******************************************************************//
+ // //
+ //******************************************************************//
+
+endmodule \ No newline at end of file
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/rtl/dvi_demo.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/dvi_demo.v
new file mode 100644
index 0000000..5659c09
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/dvi_demo.v
@@ -0,0 +1,511 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010 Xilinx, Inc.
+// This design is confidential and proprietary of Xilinx, All Rights Reserved.
+//////////////////////////////////////////////////////////////////////////////
+// ____ ____
+// / /\/ /
+// /___/ \ / Vendor: Xilinx
+// \ \ \/ Version: 1.0.0
+// \ \ Filename: dvi_demo.v
+// / / Date Created: Feb. 2010
+// /___/ /\ Last Modified: Feb. 2010
+// \ \ / \
+// \___\/\___\
+//
+// Devices: Spartan-6 FPGA
+// Purpose: DVI Pass Through Top Module Based On XLAB Atlys Board
+// Contact:
+// Reference: None
+//
+// Revision History:
+// Rev 1.0.0 - (Bob Feng) First created Feb. 2010
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// LIMITED WARRANTY AND DISCLAIMER. 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 warrant or 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 (c) 2010 Xilinx, Inc.
+// This design is confidential and proprietary of Xilinx, All Rights Reserved.
+//////////////////////////////////////////////////////////////////////////////
+
+`timescale 1 ns / 1 ps
+
+//`define DIRECTPASS
+
+module dvi_demo (
+ input wire rstbtn_n, //The pink reset button
+ input wire clk100, //100 MHz osicallator
+ input wire [3:0] RX0_TMDS,
+ input wire [3:0] RX0_TMDSB,
+ input wire [3:0] RX1_TMDS,
+ input wire [3:0] RX1_TMDSB,
+
+ output wire [3:0] TX0_TMDS,
+ output wire [3:0] TX0_TMDSB,
+ output wire [3:0] TX1_TMDS,
+ output wire [3:0] TX1_TMDSB,
+
+ input wire [1:0] SW,
+
+ output wire [7:0] LED
+);
+
+ ////////////////////////////////////////////////////
+ // 25 MHz and switch debouncers
+ ////////////////////////////////////////////////////
+ wire clk25, clk25m;
+
+ BUFIO2 #(.DIVIDE_BYPASS("FALSE"), .DIVIDE(5))
+ sysclk_div (.DIVCLK(clk25m), .IOCLK(), .SERDESSTROBE(), .I(clk100));
+
+ BUFG clk25_buf (.I(clk25m), .O(clk25));
+
+ wire [1:0] sws;
+
+ synchro #(.INITIALIZE("LOGIC0"))
+ synchro_sws_0 (.async(SW[0]),.sync(sws[0]),.clk(clk25));
+
+ synchro #(.INITIALIZE("LOGIC0"))
+ synchro_sws_1 (.async(SW[1]),.sync(sws[1]),.clk(clk25));
+
+ wire [1:0] select = sws;
+
+ reg [1:0] select_q = 2'b00;
+ reg [1:0] switch = 2'b00;
+ always @ (posedge clk25) begin
+ select_q <= select;
+
+ switch[0] = select[0] ^ select_q[0];
+ switch[1] = select[1] ^ select_q[1];
+ end
+
+ /////////////////////////
+ //
+ // Input Port 0
+ //
+ /////////////////////////
+ wire rx0_pclk, rx0_pclkx2, rx0_pclkx10, rx0_pllclk0;
+ wire rx0_plllckd;
+ wire rx0_reset;
+ wire rx0_serdesstrobe;
+ wire rx0_hsync; // hsync data
+ wire rx0_vsync; // vsync data
+ wire rx0_de; // data enable
+ wire rx0_psalgnerr; // channel phase alignment error
+ wire [7:0] rx0_red; // pixel data out
+ wire [7:0] rx0_green; // pixel data out
+ wire [7:0] rx0_blue; // pixel data out
+ wire [29:0] rx0_sdata;
+ wire rx0_blue_vld;
+ wire rx0_green_vld;
+ wire rx0_red_vld;
+ wire rx0_blue_rdy;
+ wire rx0_green_rdy;
+ wire rx0_red_rdy;
+
+ dvi_decoder dvi_rx0 (
+ //These are input ports
+ .tmdsclk_p (RX0_TMDS[3]),
+ .tmdsclk_n (RX0_TMDSB[3]),
+ .blue_p (RX0_TMDS[0]),
+ .green_p (RX0_TMDS[1]),
+ .red_p (RX0_TMDS[2]),
+ .blue_n (RX0_TMDSB[0]),
+ .green_n (RX0_TMDSB[1]),
+ .red_n (RX0_TMDSB[2]),
+ .exrst (~rstbtn_n),
+
+ //These are output ports
+ .reset (rx0_reset),
+ .pclk (rx0_pclk),
+ .pclkx2 (rx0_pclkx2),
+ .pclkx10 (rx0_pclkx10),
+ .pllclk0 (rx0_pllclk0), // PLL x10 output
+ .pllclk1 (rx0_pllclk1), // PLL x1 output
+ .pllclk2 (rx0_pllclk2), // PLL x2 output
+ .pll_lckd (rx0_plllckd),
+ .tmdsclk (rx0_tmdsclk),
+ .serdesstrobe(rx0_serdesstrobe),
+ .hsync (rx0_hsync),
+ .vsync (rx0_vsync),
+ .de (rx0_de),
+
+ .blue_vld (rx0_blue_vld),
+ .green_vld (rx0_green_vld),
+ .red_vld (rx0_red_vld),
+ .blue_rdy (rx0_blue_rdy),
+ .green_rdy (rx0_green_rdy),
+ .red_rdy (rx0_red_rdy),
+
+ .psalgnerr (rx0_psalgnerr),
+
+ .sdout (rx0_sdata),
+ .red (rx0_red),
+ .green (rx0_green),
+ .blue (rx0_blue));
+
+ /////////////////////////
+ //
+ // Input Port 1
+ //
+ /////////////////////////
+ wire rx1_pclk, rx1_pclkx2, rx1_pclkx10, rx1_pllclk0;
+ wire rx1_plllckd;
+ wire rx1_reset;
+ wire rx1_serdesstrobe;
+ wire rx1_hsync; // hsync data
+ wire rx1_vsync; // vsync data
+ wire rx1_de; // data enable
+ wire rx1_psalgnerr; // channel phase alignment error
+ wire [7:0] rx1_red; // pixel data out
+ wire [7:0] rx1_green; // pixel data out
+ wire [7:0] rx1_blue; // pixel data out
+ wire [29:0] rx1_sdata;
+ wire rx1_blue_vld;
+ wire rx1_green_vld;
+ wire rx1_red_vld;
+ wire rx1_blue_rdy;
+ wire rx1_green_rdy;
+ wire rx1_red_rdy;
+
+ dvi_decoder dvi_rx1 (
+ //These are input ports
+ .tmdsclk_p (RX1_TMDS[3]),
+ .tmdsclk_n (RX1_TMDSB[3]),
+ .blue_p (RX1_TMDS[0]),
+ .green_p (RX1_TMDS[1]),
+ .red_p (RX1_TMDS[2]),
+ .blue_n (RX1_TMDSB[0]),
+ .green_n (RX1_TMDSB[1]),
+ .red_n (RX1_TMDSB[2]),
+ .exrst (~rstbtn_n),
+
+ //These are output ports
+ .reset (rx1_reset),
+ .pclk (rx1_pclk),
+ .pclkx2 (rx1_pclkx2),
+ .pclkx10 (rx1_pclkx10),
+ .pllclk0 (rx1_pllclk0), // PLL x10 outptu
+ .pllclk1 (rx1_pllclk1), // PLL x1 output
+ .pllclk2 (rx1_pllclk2), // PLL x2 output
+ .pll_lckd (rx1_plllckd),
+ .tmdsclk (rx1_tmdsclk),
+ .serdesstrobe(rx1_serdesstrobe),
+ .hsync (rx1_hsync),
+ .vsync (rx1_vsync),
+ .de (rx1_de),
+
+ .blue_vld (rx1_blue_vld),
+ .green_vld (rx1_green_vld),
+ .red_vld (rx1_red_vld),
+ .blue_rdy (rx1_blue_rdy),
+ .green_rdy (rx1_green_rdy),
+ .red_rdy (rx1_red_rdy),
+
+ .psalgnerr (rx1_psalgnerr),
+
+ .sdout (rx1_sdata),
+ .red (rx1_red),
+ .green (rx1_green),
+ .blue (rx1_blue));
+
+ // TMDS output
+`ifdef DIRECTPASS
+ wire rstin = rx0_reset;
+ wire pclk = rx0_pclk;
+ wire pclkx2 = rx0_pclkx2;
+ wire pclkx10 = rx0_pclkx10;
+ wire serdesstrobe = rx0_serdesstrobe;
+ wire [29:0] s_data = rx0_sdata;
+
+ //
+ // 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(TX0_TMDS[3]), .OB(TX0_TMDSB[3])) ;// clock
+
+ wire [4:0] tmds_data0, tmds_data1, tmds_data2;
+ wire [2:0] tmdsint;
+
+ //
+ // 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(TX0_TMDS[0]), .OB(TX0_TMDSB[0])) ;
+ OBUFDS TMDS1 (.I(tmdsint[1]), .O(TX0_TMDS[1]), .OB(TX0_TMDSB[1])) ;
+ OBUFDS TMDS2 (.I(tmdsint[2]), .O(TX0_TMDS[2]), .OB(TX0_TMDSB[2])) ;
+
+ convert_30to15_fifo pixel2x (
+ .rst (rstin),
+ .clk (pclk),
+ .clkx2 (pclkx2),
+ .datain (s_data),
+ .dataout ({tmds_data2, tmds_data1, tmds_data0}));
+
+`else
+ /////////////////
+ //
+ // Output Port 0
+ //
+ /////////////////
+ wire tx0_de;
+ wire tx0_pclk;
+ wire tx0_pclkx2;
+ wire tx0_pclkx10;
+ wire tx0_serdesstrobe;
+ wire tx0_reset;
+ wire [7:0] tx0_blue;
+ wire [7:0] tx0_green;
+ wire [7:0] tx0_red;
+ wire tx0_hsync;
+ wire tx0_vsync;
+ wire tx0_pll_reset;
+
+ assign tx0_de = (select[0]) ? rx1_de : rx0_de;
+ assign tx0_blue = (select[0]) ? rx1_blue : rx0_blue;
+ assign tx0_green = (select[0]) ? rx1_green : rx0_green;
+ assign tx0_red = (select[0]) ? rx1_red : rx0_red;
+ assign tx0_hsync = (select[0]) ? rx1_hsync : rx0_hsync;
+ assign tx0_vsync = (select[0]) ? rx1_vsync : rx0_vsync;
+ assign tx0_pll_reset = switch[0] | ((select[0]) ? rx1_reset : rx0_reset);
+
+ //////////////////////////////////////////////////////////////////
+ // Instantiate a dedicate PLL for output port
+ //////////////////////////////////////////////////////////////////
+ wire tx0_clkfbout, tx0_clkfbin, tx0_plllckd;
+ wire tx0_pllclk0, tx0_pllclk2;
+
+ PLL_BASE # (
+ .CLKIN_PERIOD(10),
+ .CLKFBOUT_MULT(10), //set VCO to 10x of CLKIN
+ .CLKOUT0_DIVIDE(1),
+ .CLKOUT1_DIVIDE(10),
+ .CLKOUT2_DIVIDE(5),
+ .COMPENSATION("SOURCE_SYNCHRONOUS")
+ ) PLL_OSERDES_0 (
+ .CLKFBOUT(tx0_clkfbout),
+ .CLKOUT0(tx0_pllclk0),
+ .CLKOUT1(),
+ .CLKOUT2(tx0_pllclk2),
+ .CLKOUT3(),
+ .CLKOUT4(),
+ .CLKOUT5(),
+ .LOCKED(tx0_plllckd),
+ .CLKFBIN(tx0_clkfbin),
+ .CLKIN(tx0_pclk),
+ .RST(tx0_pll_reset)
+ );
+
+ //
+ // This BUFGMUX directly selects between two RX PLL pclk outputs
+ // This way we have a matched skew between the RX pclk clocks and the TX pclk
+ //
+ BUFGMUX tx0_bufg_pclk (.S(select[0]), .I1(rx1_pllclk1), .I0(rx0_pllclk1), .O(tx0_pclk));
+
+ //
+ // This BUFG is needed in order to deskew between PLL clkin and clkout
+ // So the tx0 pclkx2 and pclkx10 will have the same phase as the pclk input
+ //
+ BUFG tx0_clkfb_buf (.I(tx0_clkfbout), .O(tx0_clkfbin));
+
+ //
+ // regenerate pclkx2 for TX
+ //
+ BUFG tx0_pclkx2_buf (.I(tx0_pllclk2), .O(tx0_pclkx2));
+
+ //
+ // regenerate pclkx10 for TX
+ //
+ wire tx0_bufpll_lock;
+ BUFPLL #(.DIVIDE(5)) tx0_ioclk_buf (.PLLIN(tx0_pllclk0), .GCLK(tx0_pclkx2), .LOCKED(tx0_plllckd),
+ .IOCLK(tx0_pclkx10), .SERDESSTROBE(tx0_serdesstrobe), .LOCK(tx0_bufpll_lock));
+
+ assign tx0_reset = ~tx0_bufpll_lock;
+
+ dvi_encoder_top dvi_tx0 (
+ .pclk (tx0_pclk),
+ .pclkx2 (tx0_pclkx2),
+ .pclkx10 (tx0_pclkx10),
+ .serdesstrobe(tx0_serdesstrobe),
+ .rstin (tx0_reset),
+ .blue_din (tx0_blue),
+ .green_din (tx0_green),
+ .red_din (tx0_red),
+ .hsync (tx0_hsync),
+ .vsync (tx0_vsync),
+ .de (tx0_de),
+ .TMDS (TX0_TMDS),
+ .TMDSB (TX0_TMDSB));
+
+ /////////////////
+ //
+ // Output Port 1
+ //
+ /////////////////
+ wire tx1_de;
+ wire tx1_pclk;
+ wire tx1_pclkx2;
+ wire tx1_pclkx10;
+ wire tx1_serdesstrobe;
+ wire tx1_reset;
+ wire [7:0] tx1_blue;
+ wire [7:0] tx1_green;
+ wire [7:0] tx1_red;
+ wire tx1_hsync;
+ wire tx1_vsync;
+ wire tx1_pll_reset;
+
+ assign tx1_de = (select[1]) ? rx1_de : rx0_de;
+ assign tx1_blue = (select[1]) ? rx1_blue : rx0_blue;
+ assign tx1_green = (select[1]) ? rx1_green : rx0_green;
+ assign tx1_red = (select[1]) ? rx1_red : rx0_red;
+ assign tx1_hsync = (select[1]) ? rx1_hsync : rx0_hsync;
+ assign tx1_vsync = (select[1]) ? rx1_vsync : rx0_vsync;
+ assign tx1_pll_reset = switch[1] | ((select[1]) ? rx1_reset : rx0_reset);
+
+ //////////////////////////////////////////////////////////////////
+ // Instantiate a dedicate PLL for output port
+ //////////////////////////////////////////////////////////////////
+ wire tx1_clkfbout, tx1_clkfbin, tx1_plllckd;
+ wire tx1_pllclk0, tx1_pllclk2;
+
+ PLL_BASE # (
+ .CLKIN_PERIOD(10),
+ .CLKFBOUT_MULT(10), //set VCO to 10x of CLKIN
+ .CLKOUT0_DIVIDE(1),
+ .CLKOUT1_DIVIDE(10),
+ .CLKOUT2_DIVIDE(5),
+ .COMPENSATION("SOURCE_SYNCHRONOUS")
+ ) PLL_OSERDES_1 (
+ .CLKFBOUT(tx1_clkfbout),
+ .CLKOUT0(tx1_pllclk0),
+ .CLKOUT1(),
+ .CLKOUT2(tx1_pllclk2),
+ .CLKOUT3(),
+ .CLKOUT4(),
+ .CLKOUT5(),
+ .LOCKED(tx1_plllckd),
+ .CLKFBIN(tx1_clkfbin),
+ .CLKIN(tx1_pclk),
+ .RST(tx1_pll_reset)
+ );
+
+ //
+ // This BUFGMUX selects between two RX PLL pclk outputs
+ // This way we have a matched skew between the RX pclk clocks and the TX pclk
+ //
+ BUFGMUX tx1_bufg_pclk (.S(select[1]), .I1(rx1_pllclk1), .I0(rx0_pllclk1), .O(tx1_pclk));
+
+ //
+ // This BUFG is needed in order to deskew between PLL clkin and clkout
+ // So the tx1 pclkx2 and pclkx10 will have the same phase as the pclk input
+ //
+ BUFG tx1_clkfb_buf (.I(tx1_clkfbout), .O(tx1_clkfbin));
+
+ //
+ // regenerate pclkx2 for TX
+ //
+ BUFG tx1_pclkx2_buf (.I(tx1_pllclk2), .O(tx1_pclkx2));
+
+ //
+ // regenerate pclkx10 for TX
+ //
+ wire tx1_bufpll_lock;
+ BUFPLL #(.DIVIDE(5)) tx1_ioclk_buf (.PLLIN(tx1_pllclk0), .GCLK(tx1_pclkx2), .LOCKED(tx1_plllckd),
+ .IOCLK(tx1_pclkx10), .SERDESSTROBE(tx1_serdesstrobe), .LOCK(tx1_bufpll_lock));
+
+ assign tx1_reset = ~tx1_bufpll_lock;
+
+ dvi_encoder_top dvi_tx1 (
+ .pclk (tx1_pclk),
+ .pclkx2 (tx1_pclkx2),
+ .pclkx10 (tx1_pclkx10),
+ .serdesstrobe(tx1_serdesstrobe),
+ .rstin (tx1_reset),
+ .blue_din (tx1_blue),
+ .green_din (tx1_green),
+ .red_din (tx1_red),
+ .hsync (tx1_hsync),
+ .vsync (tx1_vsync),
+ .de (tx1_de),
+ .TMDS (TX1_TMDS),
+ .TMDSB (TX1_TMDSB));
+`endif
+
+ //////////////////////////////////////
+ // Status LED
+ //////////////////////////////////////
+ assign LED = {rx0_red_rdy, rx0_green_rdy, rx0_blue_rdy, rx1_red_rdy, rx1_green_rdy, rx1_blue_rdy,
+ rx0_de, rx1_de};
+
+endmodule
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/chnlbond.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/chnlbond.v
new file mode 100644
index 0000000..c497d86
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/chnlbond.v
@@ -0,0 +1,170 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Xilinx, Inc. 2007 www.xilinx.com
+//
+// XAPP xxx
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// File name : chnlbond.v
+//
+// Description : Channel Bonding Logic
+// TMDS channel de-skew
+//
+// 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 © 2004 Xilinx, Inc.
+// All rights reserved
+//
+//////////////////////////////////////////////////////////////////////////////
+`timescale 1 ns / 1ps
+
+module chnlbond (
+ input wire clk,
+ input wire [9:0] rawdata,
+ input wire iamvld,
+ input wire other_ch0_vld,
+ input wire other_ch1_vld,
+ input wire other_ch0_rdy,
+ input wire other_ch1_rdy,
+ output reg iamrdy,
+ output reg [9:0] sdata
+);
+
+ parameter CTRLTOKEN0 = 10'b1101010100;
+ parameter CTRLTOKEN1 = 10'b0010101011;
+ parameter CTRLTOKEN2 = 10'b0101010100;
+ parameter CTRLTOKEN3 = 10'b1010101011;
+
+ wire rawdata_vld;
+ assign rawdata_vld = other_ch0_vld & other_ch1_vld & iamvld;
+
+ reg [3:0] wa, ra;
+ reg we;
+
+ ////////////////////////////////////////////////////////
+ // FIFO Write Control Logic
+ ////////////////////////////////////////////////////////
+ always @ (posedge clk) begin
+ we <=#1 rawdata_vld;
+ end
+
+ always @ (posedge clk) begin
+ if(rawdata_vld)
+ wa <=#1 wa + 1'b1;
+ else
+ wa <=#1 4'h0;
+ end
+
+ wire [9:0] dpfo_dout;
+ DRAM16XN #(.data_width(10))
+ cbfifo_i (
+ .DATA_IN(rawdata),
+ .ADDRESS(wa),
+ .ADDRESS_DP(ra),
+ .WRITE_EN(we),
+ .CLK(clk),
+ .O_DATA_OUT(),
+ .O_DATA_OUT_DP(dpfo_dout));
+
+ always @ (posedge clk) begin
+ sdata <=#1 dpfo_dout;
+ end
+
+ ////////////////////////////////////////////////////////
+ // FIFO read Control Logic
+ ////////////////////////////////////////////////////////
+
+ ////////////////////////////////
+ // Use blank period beginning
+ // as a speical marker to
+ // align all channel together
+ ////////////////////////////////
+ reg rcvd_ctkn, rcvd_ctkn_q; //received control token
+ reg blnkbgn; //blank period begins
+ always @ (posedge clk) begin
+ rcvd_ctkn <=#1 ((sdata == CTRLTOKEN0) || (sdata == CTRLTOKEN1) || (sdata == CTRLTOKEN2) || (sdata == CTRLTOKEN3));
+ rcvd_ctkn_q <=#1 rcvd_ctkn;
+ blnkbgn <=#1 !rcvd_ctkn_q & rcvd_ctkn;
+ end
+
+ /////////////////////////////
+ //skip the current line
+ /////////////////////////////
+ wire next_blnkbgn;
+ reg skip_line;
+ always @ (posedge clk) begin
+ if(!rawdata_vld)
+ skip_line <=#1 1'b0;
+ else if(blnkbgn)
+ skip_line <=#1 1'b1;
+ end
+
+ assign next_blnkbgn = skip_line & blnkbgn;
+
+ //////////////////////////////
+ //Declare my own readiness
+ //////////////////////////////
+ always @ (posedge clk) begin
+ if(!rawdata_vld)
+ iamrdy <=#1 1'b0;
+ else if(next_blnkbgn)
+ iamrdy <=#1 1'b1;
+ end
+
+ reg rawdata_vld_q;
+ reg rawdata_vld_rising;
+ always @ (posedge clk) begin
+ rawdata_vld_q <=#1 rawdata_vld;
+ rawdata_vld_rising <=#1 rawdata_vld & !rawdata_vld_q;
+ end
+
+ //////////////////////////////////////////////////////////////////////////////////////////
+ // 1. FIFO flow through first when all channels are found valid(phase aligned)
+ // 2. When the speical marker on my channel is found, the fifo read is hold
+ // 3. Until the same markers are found across all three channels, the fifo read resumes
+ //////////////////////////////////////////////////////////////////////////////////////////
+ reg ra_en = 1'b0;
+ always @ (posedge clk) begin
+ if(rawdata_vld_rising || (other_ch0_rdy & other_ch1_rdy & iamrdy))
+ ra_en <=#1 1'b1;
+ else if(next_blnkbgn && !(other_ch0_rdy & other_ch1_rdy & iamrdy))
+ ra_en <=#1 1'b0;
+ end
+
+ /////////////////////////////////////////
+ //FIFO Read Address Counter
+ /////////////////////////////////////////
+ always @ (posedge clk) begin
+ if(!rawdata_vld)
+ ra <=#1 4'h0;
+ else if(ra_en)
+ ra <=#1 ra + 1'b1;
+ end
+
+endmodule
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/decode.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/decode.v
new file mode 100644
index 0000000..3b95485
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/decode.v
@@ -0,0 +1,237 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Xilinx, Inc. 2010 www.xilinx.com
+//
+// XAPP xxx
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// File name : decoder.v
+//
+// Description : Spartan-6 dvi decoder
+//
+//
+// 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 © 2004 Xilinx, Inc.
+// All rights reserved
+//
+//////////////////////////////////////////////////////////////////////////////
+`timescale 1 ns / 1ps
+
+module decode (
+ input wire reset, //
+ input wire pclk, // pixel clock
+ input wire pclkx2, // double pixel rate for gear box
+ input wire pclkx10, // IOCLK
+ input wire serdesstrobe, // serdesstrobe for iserdes2
+ input wire din_p, // data from dvi cable
+ input wire din_n, // data from dvi cable
+ input wire other_ch0_vld, // other channel0 has valid data now
+ input wire other_ch1_vld, // other channel1 has valid data now
+ input wire other_ch0_rdy, // other channel0 has detected a valid starting pixel
+ input wire other_ch1_rdy, // other channel1 has detected a valid starting pixel
+
+ output wire iamvld, // I have valid data now
+ output wire iamrdy, // I have detected a valid new pixel
+ output wire psalgnerr, // Phase alignment error
+ output reg c0,
+ output reg c1,
+ output reg de,
+ output reg [9:0] sdout,
+ output reg [7:0] dout);
+
+ ////////////////////////////////
+ //
+ // 5-bit to 10-bit gear box
+ //
+ ////////////////////////////////
+ wire flipgear;
+ reg flipgearx2;
+
+ always @ (posedge pclkx2) begin
+ flipgearx2 <=#1 flipgear;
+ end
+
+ reg toggle = 1'b0;
+
+ always @ (posedge pclkx2 or posedge reset)
+ if (reset == 1'b1) begin
+ toggle <= 1'b0 ;
+ end else begin
+ toggle <=#1 ~toggle;
+ end
+
+ wire rx_toggle;
+
+ assign rx_toggle = toggle ^ flipgearx2; //reverse hi-lo position
+
+ wire [4:0] raw5bit;
+ reg [4:0] raw5bit_q;
+ reg [9:0] rawword;
+
+ always @ (posedge pclkx2) begin
+ raw5bit_q <=#1 raw5bit;
+
+ if(rx_toggle) //gear from 5 bit to 10 bit
+ rawword <=#1 {raw5bit, raw5bit_q};
+ end
+
+ ////////////////////////////////
+ //
+ // bitslip signal sync to pclkx2
+ //
+ ////////////////////////////////
+ reg bitslipx2 = 1'b0;
+ reg bitslip_q = 1'b0;
+ wire bitslip;
+
+ always @ (posedge pclkx2) begin
+ bitslip_q <=#1 bitslip;
+ bitslipx2 <=#1 bitslip & !bitslip_q;
+ end
+
+ /////////////////////////////////////////////
+ //
+ // 1:5 de-serializer working at x2 pclk rate
+ //
+ /////////////////////////////////////////////
+ serdes_1_to_5_diff_data # (
+ .DIFF_TERM("FALSE"),
+ .BITSLIP_ENABLE("TRUE")
+ ) des_0 (
+ .use_phase_detector(1'b1),
+ .datain_p(din_p),
+ .datain_n(din_n),
+ .rxioclk(pclkx10),
+ .rxserdesstrobe(serdesstrobe),
+ .reset(reset),
+ .gclk(pclkx2),
+ .bitslip(bitslipx2),
+ .data_out(raw5bit)
+ );
+
+ /////////////////////////////////////////////////////
+ // Doing word boundary detection here
+ /////////////////////////////////////////////////////
+ wire [9:0] rawdata = rawword;
+
+ ///////////////////////////////////////
+ // Phase Alignment Instance
+ ///////////////////////////////////////
+ phsaligner phsalgn_0 (
+ .rst(reset),
+ .clk(pclk),
+ .sdata(rawdata),
+ .bitslip(bitslip),
+ .flipgear(flipgear),
+ .psaligned(iamvld)
+ );
+
+ assign psalgnerr = 1'b0;
+
+ ///////////////////////////////////////
+ // Per Channel De-skew Instance
+ ///////////////////////////////////////
+ wire [9:0] sdata;
+ chnlbond cbnd (
+ .clk(pclk),
+ .rawdata(rawdata),
+ .iamvld(iamvld),
+ .other_ch0_vld(other_ch0_vld),
+ .other_ch1_vld(other_ch1_vld),
+ .other_ch0_rdy(other_ch0_rdy),
+ .other_ch1_rdy(other_ch1_rdy),
+ .iamrdy(iamrdy),
+ .sdata(sdata)
+ );
+
+ /////////////////////////////////////////////////////////////////
+ // Below performs the 10B-8B decoding function defined in DVI 1.0
+ // Specification: Section 3.3.3, Figure 3-6, page 31.
+ /////////////////////////////////////////////////////////////////
+ // Distinct Control Tokens
+ parameter CTRLTOKEN0 = 10'b1101010100;
+ parameter CTRLTOKEN1 = 10'b0010101011;
+ parameter CTRLTOKEN2 = 10'b0101010100;
+ parameter CTRLTOKEN3 = 10'b1010101011;
+
+ wire [7:0] data;
+ assign data = (sdata[9]) ? ~sdata[7:0] : sdata[7:0];
+
+ always @ (posedge pclk) begin
+ if(iamrdy && other_ch0_rdy && other_ch1_rdy) begin
+ case (sdata)
+ CTRLTOKEN0: begin
+ c0 <=#1 1'b0;
+ c1 <=#1 1'b0;
+ de <=#1 1'b0;
+ end
+
+ CTRLTOKEN1: begin
+ c0 <=#1 1'b1;
+ c1 <=#1 1'b0;
+ de <=#1 1'b0;
+ end
+
+ CTRLTOKEN2: begin
+ c0 <=#1 1'b0;
+ c1 <=#1 1'b1;
+ de <=#1 1'b0;
+ end
+
+ CTRLTOKEN3: begin
+ c0 <=#1 1'b1;
+ c1 <=#1 1'b1;
+ de <=#1 1'b0;
+ end
+
+ default: begin
+ dout[0] <=#1 data[0];
+ dout[1] <=#1 (sdata[8]) ? (data[1] ^ data[0]) : (data[1] ~^ data[0]);
+ dout[2] <=#1 (sdata[8]) ? (data[2] ^ data[1]) : (data[2] ~^ data[1]);
+ dout[3] <=#1 (sdata[8]) ? (data[3] ^ data[2]) : (data[3] ~^ data[2]);
+ dout[4] <=#1 (sdata[8]) ? (data[4] ^ data[3]) : (data[4] ~^ data[3]);
+ dout[5] <=#1 (sdata[8]) ? (data[5] ^ data[4]) : (data[5] ~^ data[4]);
+ dout[6] <=#1 (sdata[8]) ? (data[6] ^ data[5]) : (data[6] ~^ data[5]);
+ dout[7] <=#1 (sdata[8]) ? (data[7] ^ data[6]) : (data[7] ~^ data[6]);
+
+ de <=#1 1'b1;
+ end
+ endcase
+
+ sdout <=#1 sdata;
+ end else begin
+ c0 <= 1'b0;
+ c1 <= 1'b0;
+ de <= 1'b0;
+ dout <= 8'h0;
+ sdout <= 10'h0;
+ end
+ end
+endmodule
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/dvi_decoder.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/dvi_decoder.v
new file mode 100644
index 0000000..038124d
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/dvi_decoder.v
@@ -0,0 +1,242 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Xilinx, Inc. 2010 www.xilinx.com
+//
+// XAPPxxx
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// File name : dvi_decoder.v
+//
+// Description : Spartan-6 DVI decoder top module
+//
+//
+// 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 © 2004 Xilinx, Inc.
+// All rights reserved
+//
+//////////////////////////////////////////////////////////////////////////////
+`timescale 1 ns / 1ps
+
+module dvi_decoder (
+ input wire tmdsclk_p, // tmds clock
+ input wire tmdsclk_n, // tmds clock
+ input wire blue_p, // Blue data in
+ input wire green_p, // Green data in
+ input wire red_p, // Red data in
+ input wire blue_n, // Blue data in
+ input wire green_n, // Green data in
+ input wire red_n, // Red data in
+ input wire exrst, // external reset input, e.g. reset button
+
+ output wire reset, // rx reset
+ output wire pclk, // regenerated pixel clock
+ output wire pclkx2, // double rate pixel clock
+ output wire pclkx10, // 10x pixel as IOCLK
+ output wire pllclk0, // send pllclk0 out so it can be fed into a different BUFPLL
+ output wire pllclk1, // PLL x1 output
+ output wire pllclk2, // PLL x2 output
+
+ output wire pll_lckd, // send pll_lckd out so it can be fed into a different BUFPLL
+ output wire serdesstrobe, // BUFPLL serdesstrobe output
+ output wire tmdsclk, // TMDS cable clock
+
+ output wire hsync, // hsync data
+ output wire vsync, // vsync data
+ output wire de, // data enable
+
+ output wire blue_vld,
+ output wire green_vld,
+ output wire red_vld,
+ output wire blue_rdy,
+ output wire green_rdy,
+ output wire red_rdy,
+
+ output wire psalgnerr,
+
+ output wire [29:0] sdout,
+ output wire [7:0] red, // pixel data out
+ output wire [7:0] green, // pixel data out
+ output wire [7:0] blue); // pixel data out
+
+
+ wire [9:0] sdout_blue, sdout_green, sdout_red;
+/*
+ assign sdout = {sdout_red[9], sdout_green[9], sdout_blue[9], sdout_red[8], sdout_green[8], sdout_blue[8],
+ sdout_red[7], sdout_green[7], sdout_blue[7], sdout_red[6], sdout_green[6], sdout_blue[6],
+ sdout_red[5], sdout_green[5], sdout_blue[5], sdout_red[4], sdout_green[4], sdout_blue[4],
+ sdout_red[3], sdout_green[3], sdout_blue[3], sdout_red[2], sdout_green[2], sdout_blue[2],
+ sdout_red[1], sdout_green[1], sdout_blue[1], sdout_red[0], sdout_green[0], sdout_blue[0]} ;
+*/
+ assign sdout = {sdout_red[9:5], sdout_green[9:5], sdout_blue[9:5],
+ sdout_red[4:0], sdout_green[4:0], sdout_blue[4:0]};
+
+ wire de_b, de_g, de_r;
+
+ assign de = de_b;
+
+ //wire blue_vld, green_vld, red_vld;
+ //wire blue_rdy, green_rdy, red_rdy;
+
+ wire blue_psalgnerr, green_psalgnerr, red_psalgnerr;
+
+ //
+ // Send TMDS clock to a differential buffer and then a BUFIO2
+ // This is a required path in Spartan-6 feed a PLL CLKIN
+ //
+ wire rxclkint;
+ IBUFDS #(.IOSTANDARD("TMDS_33"), .DIFF_TERM("FALSE")
+ ) ibuf_rxclk (.I(tmdsclk_p), .IB(tmdsclk_n), .O(rxclkint));
+
+ wire rxclk;
+
+ BUFIO2 #(.DIVIDE_BYPASS("TRUE"), .DIVIDE(1))
+ bufio_tmdsclk (.DIVCLK(rxclk), .IOCLK(), .SERDESSTROBE(), .I(rxclkint));
+
+ BUFG tmdsclk_bufg (.I(rxclk), .O(tmdsclk));
+
+ //
+ // PLL is used to generate three clocks:
+ // 1. pclk: same rate as TMDS clock
+ // 2. pclkx2: double rate of pclk used for 5:10 soft gear box and ISERDES DIVCLK
+ // 3. pclkx10: 10x rate of pclk used as IO clock
+ //
+ PLL_BASE # (
+ .CLKIN_PERIOD(10),
+ .CLKFBOUT_MULT(10), //set VCO to 10x of CLKIN
+ .CLKOUT0_DIVIDE(1),
+ .CLKOUT1_DIVIDE(10),
+ .CLKOUT2_DIVIDE(5),
+ .COMPENSATION("INTERNAL")
+ ) PLL_ISERDES (
+ .CLKFBOUT(clkfbout),
+ .CLKOUT0(pllclk0),
+ .CLKOUT1(pllclk1),
+ .CLKOUT2(pllclk2),
+ .CLKOUT3(),
+ .CLKOUT4(),
+ .CLKOUT5(),
+ .LOCKED(pll_lckd),
+ .CLKFBIN(clkfbout),
+ .CLKIN(rxclk),
+ .RST(exrst)
+ );
+
+ //
+ // Pixel Rate clock buffer
+ //
+ BUFG pclkbufg (.I(pllclk1), .O(pclk));
+
+ //////////////////////////////////////////////////////////////////
+ // 2x pclk is going to be used to drive IOSERDES2 DIVCLK
+ //////////////////////////////////////////////////////////////////
+ BUFG pclkx2bufg (.I(pllclk2), .O(pclkx2));
+
+ //////////////////////////////////////////////////////////////////
+ // 10x pclk is used to drive IOCLK network so a bit rate reference
+ // can be used by IOSERDES2
+ //////////////////////////////////////////////////////////////////
+
+ wire bufpll_lock;
+ BUFPLL #(.DIVIDE(5)) ioclk_buf (.PLLIN(pllclk0), .GCLK(pclkx2), .LOCKED(pll_lckd),
+ .IOCLK(pclkx10), .SERDESSTROBE(serdesstrobe), .LOCK(bufpll_lock));
+
+ assign reset = ~bufpll_lock;
+
+ decode dec_b (
+ .reset (reset),
+ .pclk (pclk),
+ .pclkx2 (pclkx2),
+ .pclkx10 (pclkx10),
+ .serdesstrobe (serdesstrobe),
+ .din_p (blue_p),
+ .din_n (blue_n),
+ .other_ch0_rdy(green_rdy),
+ .other_ch1_rdy(red_rdy),
+ .other_ch0_vld(green_vld),
+ .other_ch1_vld(red_vld),
+
+ .iamvld (blue_vld),
+ .iamrdy (blue_rdy),
+ .psalgnerr (blue_psalgnerr),
+ .c0 (hsync),
+ .c1 (vsync),
+ .de (de_b),
+ .sdout (sdout_blue),
+ .dout (blue)) ;
+
+ decode dec_g (
+ .reset (reset),
+ .pclk (pclk),
+ .pclkx2 (pclkx2),
+ .pclkx10 (pclkx10),
+ .serdesstrobe (serdesstrobe),
+ .din_p (green_p),
+ .din_n (green_n),
+ .other_ch0_rdy(blue_rdy),
+ .other_ch1_rdy(red_rdy),
+ .other_ch0_vld(blue_vld),
+ .other_ch1_vld(red_vld),
+
+ .iamvld (green_vld),
+ .iamrdy (green_rdy),
+ .psalgnerr (green_psalgnerr),
+ .c0 (),
+ .c1 (),
+ .de (de_g),
+ .sdout (sdout_green),
+ .dout (green)) ;
+
+ decode dec_r (
+ .reset (reset),
+ .pclk (pclk),
+ .pclkx2 (pclkx2),
+ .pclkx10 (pclkx10),
+ .serdesstrobe (serdesstrobe),
+ .din_p (red_p),
+ .din_n (red_n),
+ .other_ch0_rdy(blue_rdy),
+ .other_ch1_rdy(green_rdy),
+ .other_ch0_vld(blue_vld),
+ .other_ch1_vld(green_vld),
+
+ .iamvld (red_vld),
+ .iamrdy (red_rdy),
+ .psalgnerr (red_psalgnerr),
+ .c0 (),
+ .c1 (),
+ .de (de_r),
+ .sdout (sdout_red),
+ .dout (red)) ;
+
+
+
+ assign psalgnerr = red_psalgnerr | blue_psalgnerr | green_psalgnerr;
+
+endmodule
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/phsaligner.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/phsaligner.v
new file mode 100644
index 0000000..ee582f6
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/phsaligner.v
@@ -0,0 +1,265 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Xilinx, Inc. 2010 www.xilinx.com
+//
+// XAPP xxx - TMDS serial stream phase aligner
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// File name : phasealigner.v
+//
+// Description : This module determines whether the Spartan-6 IOSERDES
+// has validate the incoming TMDS data stream
+//
+//
+// Note:
+//
+// 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
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+`timescale 1 ns / 1ps
+
+module phsaligner # (
+ parameter OPENEYE_CNT_WD = 3, // valid open eye counter width
+ parameter CTKNCNTWD = 7, // Control Token Counter Width
+ parameter SRCHTIMERWD = 12 // Idle Timer Width
+)
+(
+ input wire rst,
+ input wire clk,
+ input wire [9:0] sdata, // 10 bit serial stream sync. to clk
+ output reg flipgear,
+ output reg bitslip,
+ output reg psaligned // FSM output
+);
+
+ parameter CTRLTOKEN0 = 10'b1101010100;
+ parameter CTRLTOKEN1 = 10'b0010101011;
+ parameter CTRLTOKEN2 = 10'b0101010100;
+ parameter CTRLTOKEN3 = 10'b1010101011;
+
+ ///////////////////////////////////////////////////////
+ // Control Token Detection
+ ///////////////////////////////////////////////////////
+ reg rcvd_ctkn, rcvd_ctkn_q;
+ reg blnkbgn; //blank period begins
+
+ always @ (posedge clk) begin
+ rcvd_ctkn <=#1 ((sdata == CTRLTOKEN0) || (sdata == CTRLTOKEN1) ||
+ (sdata == CTRLTOKEN2) || (sdata == CTRLTOKEN3));
+
+ rcvd_ctkn_q <=#1 rcvd_ctkn;
+ blnkbgn <=#1 !rcvd_ctkn_q & rcvd_ctkn;
+ end
+
+ /////////////////////////////////////////////////////
+ // Control Token Search Timer
+ //
+ // DVI 1.0 Spec. says periodic blanking should start
+ // no less than every 50ms or 20HZ
+ // 2^24 of 74.25MHZ cycles is about 200ms
+ /////////////////////////////////////////////////////
+ reg [(SRCHTIMERWD-1):0] ctkn_srh_timer;
+ reg ctkn_srh_rst; //FSM output
+
+ always @ (posedge clk) begin
+ if (ctkn_srh_rst)
+ ctkn_srh_timer <=#1 {SRCHTIMERWD{1'b0}};
+ else
+ ctkn_srh_timer <=#1 ctkn_srh_timer + 1'b1;
+ end
+
+ reg ctkn_srh_tout;
+ always @ (posedge clk) begin
+ ctkn_srh_tout <=#1 (ctkn_srh_timer == {SRCHTIMERWD{1'b1}});
+ end
+
+ /////////////////////////////////////////////////////
+ // Contorl Token Event Counter
+ //
+ // DVI 1.0 Spec. says the minimal blanking period
+ // is at least 128 pixels long in order to achieve
+ // synchronization
+ //
+ // HDMI reduces this to as little as 8
+ /////////////////////////////////////////////////////
+ reg [(CTKNCNTWD-1):0] ctkn_counter;
+ reg ctkn_cnt_rst; //FSM output
+
+ always @ (posedge clk) begin
+ if(ctkn_cnt_rst)
+ ctkn_counter <=#1 {CTKNCNTWD{1'b0}};
+ else
+ ctkn_counter <=#1 ctkn_counter + 1'b1;
+ end
+
+ reg ctkn_cnt_tout;
+ always @ (posedge clk) begin
+ ctkn_cnt_tout <=#1 (ctkn_counter == {CTKNCNTWD{1'b1}});
+ end
+
+ //////////////////////////////////////////////////////////
+ // Below starts the phase alignment state machine
+ //////////////////////////////////////////////////////////
+ parameter INIT = 6'b1 << 0;
+ parameter SEARCH = 6'b1 << 1; // Searching for control tokens
+ parameter BITSLIP = 6'b1 << 2;
+ parameter RCVDCTKN = 6'b1 << 3; // Received at one Control Token and check for more
+ parameter BLNKPRD = 6'b1 << 4;
+ parameter PSALGND = 6'b1 << 5; // Phase alignment achieved
+ parameter nSTATES = 6;
+
+ reg [(nSTATES-1):0] cstate = {{(nSTATES-1){1'b0}}, 1'b1}; //current and next states
+ reg [(nSTATES-1):0] nstate;
+
+`ifdef SIMULATION
+ // synthesis translate_off
+ reg [8*20:1] state_ascii = "INIT ";
+ always @(cstate) begin
+ if (cstate == INIT ) state_ascii <= "INIT ";
+ else if (cstate == SEARCH ) state_ascii <= "SEARCH ";
+ else if (cstate == BITSLIP ) state_ascii <= "BITSLIP ";
+ else if (cstate == RCVDCTKN ) state_ascii <= "RCVDCTKN ";
+ else if (cstate == BLNKPRD ) state_ascii <= "BLNKPRD ";
+ else state_ascii <= "PSALGND ";
+ end
+ // synthesis translate_on
+`endif
+
+ always @ (posedge clk or posedge rst) begin
+ if (rst)
+ cstate <= INIT;
+ else
+ cstate <=#1 nstate;
+ end
+
+ //////////////////////////////////////////////////////////
+ // Counter counts number of blank period detected
+ // in order to qualify the bitslip position
+ //////////////////////////////////////////////////////////
+ parameter BLNKPRD_CNT_WD = 1;
+
+ reg [(BLNKPRD_CNT_WD-1):0] blnkprd_cnt = {BLNKPRD_CNT_WD{1'b0}};
+
+ always @ (*) begin
+ case (cstate) //synthesis parallel_case full_case
+ INIT: begin
+ nstate = (ctkn_srh_tout) ? SEARCH : INIT;
+ end
+
+ SEARCH: begin
+ if(blnkbgn)
+ nstate = RCVDCTKN;
+ else
+ nstate = (ctkn_srh_tout) ? BITSLIP : SEARCH;
+ end
+
+ BITSLIP: begin
+ nstate = SEARCH;
+ end
+
+ RCVDCTKN: begin
+ if(rcvd_ctkn)
+ nstate = (ctkn_cnt_tout) ? BLNKPRD : RCVDCTKN;
+ else
+ nstate = SEARCH;
+ end
+
+ BLNKPRD: begin
+ nstate = (blnkprd_cnt == {BLNKPRD_CNT_WD{1'b1}}) ? PSALGND : SEARCH;
+ end
+
+ PSALGND: begin
+ nstate = PSALGND; // Phase aligned so hang around here
+ end
+ endcase
+ end
+
+ reg [2:0] bitslip_cnt;
+
+ always @ (posedge clk or posedge rst) begin
+ if(rst) begin
+ psaligned <=#1 1'b0; //phase alignment success flag
+ bitslip <=#1 1'b0;
+ ctkn_srh_rst <=#1 1'b1; //control token search timer reset
+ ctkn_cnt_rst <=#1 1'b1; //control token counter reset
+
+ bitslip <=#1 1'b0;
+ bitslip_cnt <=#1 3'h0;
+ flipgear <=#1 1'b0;
+ blnkprd_cnt <=#1 {BLNKPRD_CNT_WD{1'b0}};
+ end else begin
+ case (cstate) // synthesis parallel_case full_case
+ INIT: begin
+ ctkn_srh_rst <=#1 1'b0;
+ ctkn_cnt_rst <=#1 1'b1;
+ bitslip <=#1 1'b0;
+ psaligned <=#1 1'b0;
+
+ bitslip <=#1 1'b0;
+ bitslip_cnt <=#1 3'h0;
+ flipgear <=#1 1'b0;
+ blnkprd_cnt <=#1 {BLNKPRD_CNT_WD{1'b0}};
+ end
+
+ SEARCH: begin
+ ctkn_srh_rst <=#1 1'b0;
+ ctkn_cnt_rst <=#1 1'b1;
+ bitslip <=#1 1'b0;
+ psaligned <=#1 1'b0;
+ end
+
+ BITSLIP: begin
+ ctkn_srh_rst <=#1 1'b1;
+
+ bitslip <=#1 1'b1;
+ bitslip_cnt <=#1 bitslip_cnt + 1'b1;
+ flipgear <=#1 bitslip_cnt[2]; //bitslip has toggled for 4 times
+ end
+
+ RCVDCTKN: begin
+ ctkn_srh_rst <=#1 1'b0;
+ ctkn_cnt_rst <=#1 1'b0;
+ end
+
+ BLNKPRD: begin
+ blnkprd_cnt <=#1 blnkprd_cnt + 1'b1;
+ end
+
+ PSALGND: begin
+ psaligned <=#1 1'b1;
+ end
+ endcase
+ end
+ end
+
+endmodule
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/serdes_1_to_5_diff_data.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/serdes_1_to_5_diff_data.v
new file mode 100644
index 0000000..dda62e3
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/rx/serdes_1_to_5_diff_data.v
@@ -0,0 +1,403 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Xilinx, Inc. 2010 www.xilinx.com
+//
+// XAPP xxx - 1:5 Differential Data De-serializer
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// File name : serdes_1_to_5_diff_data.v
+//
+// Description : This module instantiates IODELAY2 and ISERDES2 primitives
+// to receive TMDS differential data in 1:5 format
+//
+// Note:
+//
+// Author : Bob Feng
+//////////////////////////////////////////////////////////////////////////////
+//
+// Disclaimer:
+//
+// This disclaimer is not a license and does not grant any rights to the materials
+// distributed herewith. Except as otherwise provided in a valid license issued to you
+// by Xilinx, and to the maximum extent permitted by applicable law:
+// (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS,
+// AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
+// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR
+// FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable (whether in contract
+// or tort, including negligence, or under any other theory of liability) for any loss or damage
+// of any kind or nature related to, arising under or in connection with these materials,
+// including for any direct, or any indirect, special, incidental, or consequential loss
+// or damage (including loss of data, profits, goodwill, or any type of loss or damage suffered
+// as a result of any action brought by a third party) even if such damage or loss was
+// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
+//
+// Critical Applications:
+//
+// Xilinx products are not designed or intended to be fail-safe, or for use in any application
+// requiring fail-safe performance, such as life-support or safety devices or systems,
+// Class III medical devices, nuclear facilities, applications related to the deployment of airbags,
+// or any other applications that could lead to death, personal injury, or severe property or
+// environmental damage (individually and collectively, "Critical Applications"). Customer assumes
+// the sole risk and liability of any use of Xilinx products in Critical Applications, subject only
+// to applicable laws and regulations governing limitations on product liability.
+//
+// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+`timescale 1ps/1ps
+
+module serdes_1_to_5_diff_data # (
+ parameter DIFF_TERM = "TRUE",
+ parameter SIM_TAP_DELAY = 49,
+ parameter BITSLIP_ENABLE = "FALSE"
+)(
+ input wire use_phase_detector, // '1' enables the phase detector logic
+ input wire datain_p, // Input from LVDS receiver pin
+ input wire datain_n, // Input from LVDS receiver pin
+ input wire rxioclk, // IO Clock network
+ input wire rxserdesstrobe, // Parallel data capture strobe
+ input wire reset, // Reset line
+ input wire gclk, // Global clock
+ input wire bitslip, // Bitslip control line
+ output wire [4:0] data_out // Output data
+);
+
+ wire ddly_m;
+ wire ddly_s;
+ wire busys;
+ wire rx_data_in;
+ wire cascade;
+ wire pd_edge;
+ reg [8:0] counter;
+ reg [3:0] state;
+ reg cal_data_sint;
+ wire busy_data;
+ reg busy_data_d;
+ wire cal_data_slave;
+ reg enable;
+ reg cal_data_master;
+ reg rst_data;
+ reg inc_data_int;
+ wire inc_data;
+ reg ce_data;
+ reg valid_data_d;
+ reg incdec_data_d;
+ reg [4:0] pdcounter;
+ wire valid_data;
+ wire incdec_data;
+ reg flag;
+ reg mux;
+ reg ce_data_inta ;
+ wire [1:0] incdec_data_or;
+ wire incdec_data_im;
+ wire [1:0] valid_data_or;
+ wire valid_data_im;
+ wire [1:0] busy_data_or;
+ wire all_ce;
+
+ wire [1:0] debug_in = 2'b00;
+
+ assign busy_data = busys ;
+
+ assign cal_data_slave = cal_data_sint ;
+
+ /////////////////////////////////////////////////
+ //
+ // IDELAY Calibration FSM
+ //
+ /////////////////////////////////////////////////
+ always @ (posedge gclk or posedge reset)
+ begin
+ if (reset == 1'b1) begin
+ state <= 0 ;
+ cal_data_master <= 1'b0 ;
+ cal_data_sint <= 1'b0 ;
+ counter <= 9'h000 ;
+ enable <= 1'b0 ;
+ mux <= 1'h1 ;
+ end
+ else begin
+ counter <= counter + 9'h001 ;
+ if (counter[8] == 1'b1) begin
+ counter <= 9'h000 ;
+ end
+ if (counter[5] == 1'b1) begin
+ enable <= 1'b1 ;
+ end
+ if (state == 0 && enable == 1'b1) begin // Wait for IODELAY to be available
+ cal_data_master <= 1'b0 ;
+ cal_data_sint <= 1'b0 ;
+ rst_data <= 1'b0 ;
+ if (busy_data_d == 1'b0) begin
+ state <= 1 ;
+ end
+ end
+ else if (state == 1) begin // Issue calibrate command to both master and slave, needed for simulation, not for the silicon
+ cal_data_master <= 1'b1 ;
+ cal_data_sint <= 1'b1 ;
+ if (busy_data_d == 1'b1) begin // and wait for command to be accepted
+ state <= 2 ;
+ end
+ end
+ else if (state == 2) begin // Now RST master and slave IODELAYs needed for simulation, not for the silicon
+ cal_data_master <= 1'b0 ;
+ cal_data_sint <= 1'b0 ;
+ if (busy_data_d == 1'b0) begin
+ rst_data <= 1'b1 ;
+ state <= 3 ;
+ end
+ end
+ else if (state == 3) begin // Wait for IODELAY to be available
+ rst_data <= 1'b0 ;
+ if (busy_data_d == 1'b0) begin
+ state <= 4 ;
+ end
+ end
+ else if (state == 4) begin // Wait for occasional enable
+ if (counter[8] == 1'b1) begin
+ state <= 5 ;
+ end
+ end
+ else if (state == 5) begin // Calibrate slave only
+ if (busy_data_d == 1'b0) begin
+ cal_data_sint <= 1'b1 ;
+ state <= 6 ;
+ end
+ end
+ else if (state == 6) begin // Wait for command to be accepted
+ cal_data_sint <= 1'b0 ;
+ if (busy_data_d == 1'b1) begin
+ state <= 7 ;
+ end
+ end
+ else if (state == 7) begin // Wait for all IODELAYs to be available, ie CAL command finished
+ cal_data_sint <= 1'b0 ;
+ if (busy_data_d == 1'b0) begin
+ state <= 4 ;
+ end
+ end
+ end
+ end
+
+always @ (posedge gclk or posedge reset) // Per-bit phase detection state machine
+begin
+if (reset == 1'b1) begin
+ pdcounter <= 5'b1000 ;
+ ce_data_inta <= 1'b0 ;
+ flag <= 1'b0 ; // flag is there to only allow one inc or dec per cal (test)
+end
+else begin
+ busy_data_d <= busy_data_or[1] ;
+ if (use_phase_detector == 1'b1) begin // decide whther pd is used
+ incdec_data_d <= incdec_data_or[1] ;
+ valid_data_d <= valid_data_or[1] ;
+ if (ce_data_inta == 1'b1) begin
+ ce_data = mux ;
+ end
+ else begin
+ ce_data = 64'h0000000000000000 ;
+ end
+ if (state == 7) begin
+ flag <= 1'b0 ;
+ end
+ else if (state != 4 || busy_data_d == 1'b1) begin // Reset filter if state machine issues a cal command or unit is busy
+ pdcounter <= 5'b10000 ;
+ ce_data_inta <= 1'b0 ;
+ end
+ else if (pdcounter == 5'b11111 && flag == 1'b0) begin // Filter has reached positive max - increment the tap count
+ ce_data_inta <= 1'b1 ;
+ inc_data_int <= 1'b1 ;
+ pdcounter <= 5'b10000 ;
+ flag <= 1'b1 ;
+ end
+ else if (pdcounter == 5'b00000 && flag == 1'b0) begin // Filter has reached negative max - decrement the tap count
+ ce_data_inta <= 1'b1 ;
+ inc_data_int <= 1'b0 ;
+ pdcounter <= 5'b10000 ;
+ flag <= 1'b1 ;
+ end
+ else if (valid_data_d == 1'b1) begin // increment filter
+ ce_data_inta <= 1'b0 ;
+ if (incdec_data_d == 1'b1 && pdcounter != 5'b11111) begin
+ pdcounter <= pdcounter + 5'b00001 ;
+ end
+ else if (incdec_data_d == 1'b0 && pdcounter != 5'b00000) begin // decrement filter
+ pdcounter <= pdcounter + 5'b11111 ;
+ end
+ end
+ else begin
+ ce_data_inta <= 1'b0 ;
+ end
+ end
+ else begin
+ ce_data = all_ce ;
+ inc_data_int = debug_in[1] ;
+ end
+end
+end
+
+assign inc_data = inc_data_int ;
+
+assign incdec_data_or[0] = 1'b0 ; // Input Mux - Initialise generate loop OR gates
+assign valid_data_or[0] = 1'b0 ;
+assign busy_data_or[0] = 1'b0 ;
+
+assign incdec_data_im = incdec_data & mux; // Input muxes
+assign incdec_data_or[1] = incdec_data_im | incdec_data_or; // AND gates to allow just one signal through at a tome
+assign valid_data_im = valid_data & mux; // followed by an OR
+assign valid_data_or[1] = valid_data_im | valid_data_or; // for the three inputs from each PD
+assign busy_data_or[1] = busy_data | busy_data_or; // The busy signals just need an OR gate
+
+assign all_ce = debug_in[0] ;
+
+IBUFDS #(
+ .DIFF_TERM (DIFF_TERM))
+data_in (
+ .I (datain_p),
+ .IB (datain_n),
+ .O (rx_data_in)
+);
+
+//
+// Master IDELAY
+//
+IODELAY2 #(
+ .DATA_RATE ("SDR"),
+ .IDELAY_VALUE (0),
+ .IDELAY2_VALUE (0),
+ .IDELAY_MODE ("NORMAL" ),
+ .ODELAY_VALUE (0),
+ .IDELAY_TYPE ("DIFF_PHASE_DETECTOR"),
+ .COUNTER_WRAPAROUND ("STAY_AT_LIMIT"), //("WRAPAROUND"),
+ .DELAY_SRC ("IDATAIN"),
+ .SERDES_MODE ("MASTER"),
+ .SIM_TAPDELAY_VALUE (SIM_TAP_DELAY)
+) iodelay_m (
+ .IDATAIN (rx_data_in), // data from IBUFDS
+ .TOUT (), // tri-state signal to IOB
+ .DOUT (), // output data to IOB
+ .T (1'b1), // tri-state control from OLOGIC/OSERDES2
+ .ODATAIN (1'b0), // data from OLOGIC/OSERDES2
+ .DATAOUT (ddly_m), // Output data 1 to ILOGIC/ISERDES2
+ .DATAOUT2 (), // Output data 2 to ILOGIC/ISERDES2
+ .IOCLK0 (rxioclk), // High speed clock for calibration
+ .IOCLK1 (1'b0), // High speed clock for calibration
+ .CLK (gclk), // Fabric clock (GCLK) for control signals
+ .CAL (cal_data_master), // Calibrate control signal
+ .INC (inc_data), // Increment counter
+ .CE (ce_data), // Clock Enable
+ .RST (rst_data), // Reset delay line
+ .BUSY () // output signal indicating sync circuit has finished / calibration has finished
+);
+
+//
+// Slave IDELAY
+//
+IODELAY2 #(
+ .DATA_RATE ("SDR"),
+ .IDELAY_VALUE (0),
+ .IDELAY2_VALUE (0),
+ .IDELAY_MODE ("NORMAL" ),
+ .ODELAY_VALUE (0),
+ .IDELAY_TYPE ("DIFF_PHASE_DETECTOR"),
+ .COUNTER_WRAPAROUND ("WRAPAROUND"),
+ .DELAY_SRC ("IDATAIN"),
+ .SERDES_MODE ("SLAVE"),
+ .SIM_TAPDELAY_VALUE (SIM_TAP_DELAY)
+) iodelay_s (
+ .IDATAIN (rx_data_in), // data from IBUFDS
+ .TOUT (), // tri-state signal to IOB
+ .DOUT (), // output data to IOB
+ .T (1'b1), // tri-state control from OLOGIC/OSERDES2
+ .ODATAIN (1'b0), // data from OLOGIC/OSERDES2
+ .DATAOUT (ddly_s), // Slave output data to ILOGIC/ISERDES2
+ .DATAOUT2 (), //
+ .IOCLK0 (rxioclk), // High speed IO clock for calibration
+ .IOCLK1 (1'b0),
+ .CLK (gclk), // Fabric clock (GCLK) for control signals
+ .CAL (cal_data_slave), // Calibrate control signal
+ .INC (inc_data), // Increment counter
+ .CE (ce_data), // Clock Enable
+ .RST (rst_data), // Reset delay line
+ .BUSY (busys) // output signal indicating sync circuit has finished / calibration has finished
+);
+
+//
+// Master ISERDES
+//
+
+ISERDES2 #(
+ .DATA_WIDTH (5),
+ .DATA_RATE ("SDR"),
+ .BITSLIP_ENABLE (BITSLIP_ENABLE),
+ .SERDES_MODE ("MASTER"),
+ .INTERFACE_TYPE ("RETIMED"))
+iserdes_m (
+ .D (ddly_m),
+ .CE0 (1'b1),
+ .CLK0 (rxioclk),
+ .CLK1 (1'b0),
+ .IOCE (rxserdesstrobe),
+ .RST (reset),
+ .CLKDIV (gclk),
+ .SHIFTIN (pd_edge),
+ .BITSLIP (bitslip),
+ .FABRICOUT (),
+ .Q4 (data_out[4]),
+ .Q3 (data_out[3]),
+ .Q2 (data_out[2]),
+ .Q1 (data_out[1]),
+ .DFB (),
+ .CFB0 (),
+ .CFB1 (),
+ .VALID (valid_data),
+ .INCDEC (incdec_data),
+ .SHIFTOUT (cascade));
+
+//
+// Slave ISERDES
+//
+
+ISERDES2 #(
+ .DATA_WIDTH (5),
+ .DATA_RATE ("SDR"),
+ .BITSLIP_ENABLE (BITSLIP_ENABLE),
+ .SERDES_MODE ("SLAVE"),
+ .INTERFACE_TYPE ("RETIMED")
+) iserdes_s (
+ .D (ddly_s),
+ .CE0 (1'b1),
+ .CLK0 (rxioclk),
+ .CLK1 (1'b0),
+ .IOCE (rxserdesstrobe),
+ .RST (reset),
+ .CLKDIV (gclk),
+ .SHIFTIN (cascade),
+ .BITSLIP (bitslip),
+ .FABRICOUT (),
+ .Q4 (data_out[0]),
+ .Q3 (),
+ .Q2 (),
+ .Q1 (),
+ .DFB (),
+ .CFB0 (),
+ .CFB1 (),
+ .VALID (),
+ .INCDEC (),
+ .SHIFTOUT (pd_edge));
+
+
+reg [7:0] rxpdcntr = 8'h7f;
+always @ (posedge gclk or posedge reset) begin
+ if (reset)
+ rxpdcntr <= 8'h7f;
+ else if (ce_data)
+ if (inc_data)
+ rxpdcntr <= rxpdcntr + 1'b1;
+ else
+ rxpdcntr <= rxpdcntr - 1'b1;
+end
+
+endmodule
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/convert_30to15_fifo.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/convert_30to15_fifo.v
new file mode 100644
index 0000000..8ad8727
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/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/fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/dvi_encoder.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/dvi_encoder.v
new file mode 100644
index 0000000..963a96b
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/dvi_encoder.v
@@ -0,0 +1,103 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// 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
+//
+//////////////////////////////////////////////////////////////////////////////
+`timescale 1 ns / 1ps
+
+module dvi_encoder (
+input wire clkin, // pixel clock
+input wire clkx2in, // pixel clock x2
+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 [4:0] tmds_data0,
+output wire [4:0] tmds_data1,
+output wire [4:0] tmds_data2); // 5-bit busses converted from 10-bit
+
+wire [9:0] red ;
+wire [9:0] green ;
+wire [9:0] blue ;
+
+encode encb (
+ .clkin (clkin),
+ .rstin (rstin),
+ .din (blue_din),
+ .c0 (hsync),
+ .c1 (vsync),
+ .de (de),
+ .dout (blue)) ;
+
+encode encg (
+ .clkin (clkin),
+ .rstin (rstin),
+ .din (green_din),
+ .c0 (1'b0),
+ .c1 (1'b0),
+ .de (de),
+ .dout (green)) ;
+
+encode encr (
+ .clkin (clkin),
+ .rstin (rstin),
+ .din (red_din),
+ .c0 (1'b0),
+ .c1 (1'b0),
+ .de (de),
+ .dout (red)) ;
+
+wire [29:0] s_data = {red[9:5], green[9:5], blue[9:5],
+ red[4:0], green[4:0], blue[4:0]};
+
+convert_30to15_fifo pixel2x (
+ .rst (rstin),
+ .clk (clkin),
+ .clkx2 (clkx2in),
+ .datain (s_data),
+ .dataout ({tmds_data2, tmds_data1, tmds_data0}));
+
+endmodule
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/dvi_encoder_top.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/dvi_encoder_top.v
new file mode 100644
index 0000000..fcfefe0
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/dvi_encoder_top.v
@@ -0,0 +1,172 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// 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
+//
+//////////////////////////////////////////////////////////////////////////////
+`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);
+
+ wire [9:0] red ;
+ wire [9:0] green ;
+ wire [9:0] blue ;
+
+ 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])) ;
+
+ encode encb (
+ .clkin (pclk),
+ .rstin (rstin),
+ .din (blue_din),
+ .c0 (hsync),
+ .c1 (vsync),
+ .de (de),
+ .dout (blue)) ;
+
+ encode encg (
+ .clkin (pclk),
+ .rstin (rstin),
+ .din (green_din),
+ .c0 (1'b0),
+ .c1 (1'b0),
+ .de (de),
+ .dout (green)) ;
+
+ encode encr (
+ .clkin (pclk),
+ .rstin (rstin),
+ .din (red_din),
+ .c0 (1'b0),
+ .c1 (1'b0),
+ .de (de),
+ .dout (red)) ;
+
+ wire [29:0] s_data = {red[9:5], green[9:5], blue[9:5],
+ red[4:0], green[4:0], blue[4:0]};
+
+ convert_30to15_fifo pixel2x (
+ .rst (rstin),
+ .clk (pclk),
+ .clkx2 (pclkx2),
+ .datain (s_data),
+ .dataout ({tmds_data2, tmds_data1, tmds_data0}));
+
+endmodule
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/encode.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/encode.v
new file mode 100644
index 0000000..0a7f13d
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/encode.v
@@ -0,0 +1,191 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// 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
+//
+//////////////////////////////////////////////////////////////////////////////
+`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
+);
+
+ ////////////////////////////////////////////////////////////
+ // 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;
+
+ 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;
+ 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 (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
+ end
+ end
+
+endmodule
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/serdes_n_to_1.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/serdes_n_to_1.v
new file mode 100644
index 0000000..bc384b6
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/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
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/vtc_demo.v b/fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/vtc_demo.v
new file mode 100644
index 0000000..2194851
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/rtl/tx/vtc_demo.v
@@ -0,0 +1,674 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2009 Xilinx, Inc.
+// This design is confidential and proprietary of Xilinx, All Rights Reserved.
+//////////////////////////////////////////////////////////////////////////////
+// ____ ____
+// / /\/ /
+// /___/ \ / Vendor: Xilinx
+// \ \ \/ Version: 1.0.0
+// \ \ Filename: vtc_demo.v
+// / / Date Created: April 8, 2009
+// /___/ /\ Author: Bob Feng
+// \ \ / \
+// \___\/\___\
+//
+// Devices: Spartan-6 Generation FPGA
+// Purpose: SP601 board demo top level
+// Contact:
+// Reference: None
+//
+// Revision History:
+//
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// LIMITED WARRANTY AND DISCLAIMER. 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 warrant or 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 (c) 2009 Xilinx, Inc.
+// This design is confidential and proprietary of Xilinx, All Rights Reserved.
+//////////////////////////////////////////////////////////////////////////////
+
+`timescale 1 ps / 1 ps
+
+module vtc_demo (
+ input wire RSTBTN,
+
+ input wire SYS_CLK,
+
+ input wire [3:0] SW,
+
+ output wire [3:0] TMDS,
+ output wire [3:0] TMDSB,
+ output wire [3:0] LED,
+ output wire [1:0] DEBUG
+);
+
+ //******************************************************************//
+ // Create global clock and synchronous system reset. //
+ //******************************************************************//
+ wire locked;
+ wire reset;
+
+ wire clk50m, clk50m_bufg;
+
+ wire pwrup;
+
+ IBUF sysclk_buf (.I(SYS_CLK), .O(sysclk));
+
+ BUFIO2 #(.DIVIDE_BYPASS("FALSE"), .DIVIDE(2))
+ sysclk_div (.DIVCLK(clk50m), .IOCLK(), .SERDESSTROBE(), .I(sysclk));
+
+ BUFG clk50m_bufgbufg (.I(clk50m), .O(clk50m_bufg));
+
+ wire pclk_lckd;
+
+//`ifdef SIMULATION
+// assign pwrup = 1'b0;
+//`else
+ SRL16E #(.INIT(16'h1)) pwrup_0 (
+ .Q(pwrup),
+ .A0(1'b1),
+ .A1(1'b1),
+ .A2(1'b1),
+ .A3(1'b1),
+ .CE(pclk_lckd),
+ .CLK(clk50m_bufg),
+ .D(1'b0)
+ );
+//`endif
+
+ //////////////////////////////////////
+ /// Switching screen formats
+ //////////////////////////////////////
+ wire busy;
+ wire [3:0] sws_sync; //synchronous output
+
+ synchro #(.INITIALIZE("LOGIC0"))
+ synchro_sws_3 (.async(SW[3]),.sync(sws_sync[3]),.clk(clk50m_bufg));
+
+ synchro #(.INITIALIZE("LOGIC0"))
+ synchro_sws_2 (.async(SW[2]),.sync(sws_sync[2]),.clk(clk50m_bufg));
+
+ synchro #(.INITIALIZE("LOGIC0"))
+ synchro_sws_1 (.async(SW[1]),.sync(sws_sync[1]),.clk(clk50m_bufg));
+
+ synchro #(.INITIALIZE("LOGIC0"))
+ synchro_sws_0 (.async(SW[0]),.sync(sws_sync[0]),.clk(clk50m_bufg));
+
+ reg [3:0] sws_sync_q;
+ always @ (posedge clk50m_bufg)
+ begin
+ sws_sync_q <= sws_sync;
+ end
+
+ wire sw0_rdy, sw1_rdy, sw2_rdy, sw3_rdy;
+
+ debnce debsw0 (
+ .sync(sws_sync_q[0]),
+ .debnced(sw0_rdy),
+ .clk(clk50m_bufg));
+
+ debnce debsw1 (
+ .sync(sws_sync_q[1]),
+ .debnced(sw1_rdy),
+ .clk(clk50m_bufg));
+
+ debnce debsw2 (
+ .sync(sws_sync_q[2]),
+ .debnced(sw2_rdy),
+ .clk(clk50m_bufg));
+
+ debnce debsw3 (
+ .sync(sws_sync_q[3]),
+ .debnced(sw3_rdy),
+ .clk(clk50m_bufg));
+
+ reg switch = 1'b0;
+ always @ (posedge clk50m_bufg)
+ begin
+ switch <= pwrup | sw0_rdy | sw1_rdy | sw2_rdy | sw3_rdy;
+ end
+
+ wire gopclk;
+ SRL16E SRL16E_0 (
+ .Q(gopclk),
+ .A0(1'b1),
+ .A1(1'b1),
+ .A2(1'b1),
+ .A3(1'b1),
+ .CE(1'b1),
+ .CLK(clk50m_bufg),
+ .D(switch)
+ );
+ // The following defparam declaration
+ defparam SRL16E_0.INIT = 16'h0;
+
+ parameter SW_VGA = 4'b0000;
+ parameter SW_SVGA = 4'b0001;
+ parameter SW_XGA = 4'b0011;
+ parameter SW_HDTV720P = 4'b0010;
+ parameter SW_SXGA = 4'b1000;
+
+ reg [7:0] pclk_M, pclk_D;
+ always @ (posedge clk50m_bufg)
+ begin
+ if(switch) begin
+ case (sws_sync_q)
+ SW_VGA: //25 MHz pixel clock
+ begin
+ pclk_M <= 8'd2 - 8'd1;
+ pclk_D <= 8'd4 - 8'd1;
+ end
+
+ SW_SVGA: //40 MHz pixel clock
+ begin
+ pclk_M <= 8'd4 - 8'd1;
+ pclk_D <= 8'd5 - 8'd1;
+ end
+
+ SW_XGA: //65 MHz pixel clock
+ begin
+ pclk_M <= 8'd13 - 8'd1;
+ pclk_D <= 8'd10 - 8'd1;
+ end
+
+ SW_SXGA: //108 MHz pixel clock
+ begin
+ pclk_M <= 8'd54 - 8'd1;
+ pclk_D <= 8'd25 - 8'd1;
+ end
+
+ default: //74.25 MHz pixel clock
+ begin
+ pclk_M <= 8'd37 - 8'd1;
+ pclk_D <= 8'd25 - 8'd1;
+ end
+ endcase
+ end
+ end
+
+ //
+ // DCM_CLKGEN SPI controller
+ //
+ wire progdone, progen, progdata;
+ dcmspi dcmspi_0 (
+ .RST(switch), //Synchronous Reset
+ .PROGCLK(clk50m_bufg), //SPI clock
+ .PROGDONE(progdone), //DCM is ready to take next command
+ .DFSLCKD(pclk_lckd),
+ .M(pclk_M), //DCM M value
+ .D(pclk_D), //DCM D value
+ .GO(gopclk), //Go programme the M and D value into DCM(1 cycle pulse)
+ .BUSY(busy),
+ .PROGEN(progen), //SlaveSelect,
+ .PROGDATA(progdata) //CommandData
+ );
+
+ //
+ // DCM_CLKGEN to generate a pixel clock with a variable frequency
+ //
+ wire clkfx, pclk;
+ DCM_CLKGEN #(
+ .CLKFX_DIVIDE (21),
+ .CLKFX_MULTIPLY (31),
+ .CLKIN_PERIOD(20.000)
+ )
+ PCLK_GEN_INST (
+ .CLKFX(clkfx),
+ .CLKFX180(),
+ .CLKFXDV(),
+ .LOCKED(pclk_lckd),
+ .PROGDONE(progdone),
+ .STATUS(),
+ .CLKIN(clk50m),
+ .FREEZEDCM(1'b0),
+ .PROGCLK(clk50m_bufg),
+ .PROGDATA(progdata),
+ .PROGEN(progen),
+ .RST(1'b0)
+ );
+
+
+ wire pllclk0, pllclk1, pllclk2;
+ wire pclkx2, pclkx10, pll_lckd;
+ wire clkfbout;
+
+ //
+ // Pixel Rate clock buffer
+ //
+ BUFG pclkbufg (.I(pllclk1), .O(pclk));
+
+ //////////////////////////////////////////////////////////////////
+ // 2x pclk is going to be used to drive OSERDES2
+ // on the GCLK side
+ //////////////////////////////////////////////////////////////////
+ BUFG pclkx2bufg (.I(pllclk2), .O(pclkx2));
+
+ //////////////////////////////////////////////////////////////////
+ // 10x pclk is used to drive IOCLK network so a bit rate reference
+ // can be used by OSERDES2
+ //////////////////////////////////////////////////////////////////
+ PLL_BASE # (
+ .CLKIN_PERIOD(13),
+ .CLKFBOUT_MULT(10), //set VCO to 10x of CLKIN
+ .CLKOUT0_DIVIDE(1),
+ .CLKOUT1_DIVIDE(10),
+ .CLKOUT2_DIVIDE(5),
+ .COMPENSATION("INTERNAL")
+ ) PLL_OSERDES (
+ .CLKFBOUT(clkfbout),
+ .CLKOUT0(pllclk0),
+ .CLKOUT1(pllclk1),
+ .CLKOUT2(pllclk2),
+ .CLKOUT3(),
+ .CLKOUT4(),
+ .CLKOUT5(),
+ .LOCKED(pll_lckd),
+ .CLKFBIN(clkfbout),
+ .CLKIN(clkfx),
+ .RST(~pclk_lckd)
+ );
+
+ wire serdesstrobe;
+ wire bufpll_lock;
+ BUFPLL #(.DIVIDE(5)) ioclk_buf (.PLLIN(pllclk0), .GCLK(pclkx2), .LOCKED(pll_lckd),
+ .IOCLK(pclkx10), .SERDESSTROBE(serdesstrobe), .LOCK(bufpll_lock));
+
+ synchro #(.INITIALIZE("LOGIC1"))
+ synchro_reset (.async(!pll_lckd),.sync(reset),.clk(pclk));
+
+///////////////////////////////////////////////////////////////////////////
+// Video Timing Parameters
+///////////////////////////////////////////////////////////////////////////
+ //1280x1024@60HZ
+ parameter HPIXELS_SXGA = 11'd1280; //Horizontal Live Pixels
+ parameter VLINES_SXGA = 11'd1024; //Vertical Live ines
+ parameter HSYNCPW_SXGA = 11'd112; //HSYNC Pulse Width
+ parameter VSYNCPW_SXGA = 11'd3; //VSYNC Pulse Width
+ parameter HFNPRCH_SXGA = 11'd48; //Horizontal Front Portch
+ parameter VFNPRCH_SXGA = 11'd1; //Vertical Front Portch
+ parameter HBKPRCH_SXGA = 11'd248; //Horizontal Front Portch
+ parameter VBKPRCH_SXGA = 11'd38; //Vertical Front Portch
+
+ //1280x720@60HZ
+ parameter HPIXELS_HDTV720P = 11'd1280; //Horizontal Live Pixels
+ parameter VLINES_HDTV720P = 11'd720; //Vertical Live ines
+ parameter HSYNCPW_HDTV720P = 11'd80; //HSYNC Pulse Width
+ parameter VSYNCPW_HDTV720P = 11'd5; //VSYNC Pulse Width
+ parameter HFNPRCH_HDTV720P = 11'd72; //Horizontal Front Portch
+ parameter VFNPRCH_HDTV720P = 11'd3; //Vertical Front Portch
+ parameter HBKPRCH_HDTV720P = 11'd216; //Horizontal Front Portch
+ parameter VBKPRCH_HDTV720P = 11'd22; //Vertical Front Portch
+
+ //1024x768@60HZ
+ parameter HPIXELS_XGA = 11'd1024; //Horizontal Live Pixels
+ parameter VLINES_XGA = 11'd768; //Vertical Live ines
+ parameter HSYNCPW_XGA = 11'd136; //HSYNC Pulse Width
+ parameter VSYNCPW_XGA = 11'd6; //VSYNC Pulse Width
+ parameter HFNPRCH_XGA = 11'd24; //Horizontal Front Portch
+ parameter VFNPRCH_XGA = 11'd3; //Vertical Front Portch
+ parameter HBKPRCH_XGA = 11'd160; //Horizontal Front Portch
+ parameter VBKPRCH_XGA = 11'd29; //Vertical Front Portch
+
+ //800x600@60HZ
+ parameter HPIXELS_SVGA = 11'd800; //Horizontal Live Pixels
+ parameter VLINES_SVGA = 11'd600; //Vertical Live ines
+ parameter HSYNCPW_SVGA = 11'd128; //HSYNC Pulse Width
+ parameter VSYNCPW_SVGA = 11'd4; //VSYNC Pulse Width
+ parameter HFNPRCH_SVGA = 11'd40; //Horizontal Front Portch
+ parameter VFNPRCH_SVGA = 11'd1; //Vertical Front Portch
+ parameter HBKPRCH_SVGA = 11'd88; //Horizontal Front Portch
+ parameter VBKPRCH_SVGA = 11'd23; //Vertical Front Portch
+
+ //640x480@60HZ
+ parameter HPIXELS_VGA = 11'd640; //Horizontal Live Pixels
+ parameter VLINES_VGA = 11'd480; //Vertical Live ines
+ parameter HSYNCPW_VGA = 11'd96; //HSYNC Pulse Width
+ parameter VSYNCPW_VGA = 11'd2; //VSYNC Pulse Width
+ parameter HFNPRCH_VGA = 11'd16; //Horizontal Front Portch
+ parameter VFNPRCH_VGA = 11'd11; //Vertical Front Portch
+ parameter HBKPRCH_VGA = 11'd48; //Horizontal Front Portch
+ parameter VBKPRCH_VGA = 11'd31; //Vertical Front Portch
+
+ reg [10:0] tc_hsblnk;
+ reg [10:0] tc_hssync;
+ reg [10:0] tc_hesync;
+ reg [10:0] tc_heblnk;
+ reg [10:0] tc_vsblnk;
+ reg [10:0] tc_vssync;
+ reg [10:0] tc_vesync;
+ reg [10:0] tc_veblnk;
+
+ wire [3:0] sws_clk; //clk synchronous output
+
+ synchro #(.INITIALIZE("LOGIC0"))
+ clk_sws_3 (.async(SW[3]),.sync(sws_clk[3]),.clk(pclk));
+
+ synchro #(.INITIALIZE("LOGIC0"))
+ clk_sws_2 (.async(SW[2]),.sync(sws_clk[2]),.clk(pclk));
+
+ synchro #(.INITIALIZE("LOGIC0"))
+ clk_sws_1 (.async(SW[1]),.sync(sws_clk[1]),.clk(pclk));
+
+ synchro #(.INITIALIZE("LOGIC0"))
+ clk_sws_0 (.async(SW[0]),.sync(sws_clk[0]),.clk(pclk));
+
+ reg [3:0] sws_clk_sync; //clk synchronous output
+ always @ (posedge pclk)
+ begin
+ sws_clk_sync <= sws_clk;
+ end
+
+ reg hvsync_polarity; //1-Negative, 0-Positive
+ always @ (*)
+ begin
+ case (sws_clk_sync)
+ SW_VGA:
+ begin
+ hvsync_polarity = 1'b1;
+
+ tc_hsblnk = HPIXELS_VGA - 11'd1;
+ tc_hssync = HPIXELS_VGA - 11'd1 + HFNPRCH_VGA;
+ tc_hesync = HPIXELS_VGA - 11'd1 + HFNPRCH_VGA + HSYNCPW_VGA;
+ tc_heblnk = HPIXELS_VGA - 11'd1 + HFNPRCH_VGA + HSYNCPW_VGA + HBKPRCH_VGA;
+ tc_vsblnk = VLINES_VGA - 11'd1;
+ tc_vssync = VLINES_VGA - 11'd1 + VFNPRCH_VGA;
+ tc_vesync = VLINES_VGA - 11'd1 + VFNPRCH_VGA + VSYNCPW_VGA;
+ tc_veblnk = VLINES_VGA - 11'd1 + VFNPRCH_VGA + VSYNCPW_VGA + VBKPRCH_VGA;
+ end
+
+ SW_SVGA:
+ begin
+ hvsync_polarity = 1'b0;
+
+ tc_hsblnk = HPIXELS_SVGA - 11'd1;
+ tc_hssync = HPIXELS_SVGA - 11'd1 + HFNPRCH_SVGA;
+ tc_hesync = HPIXELS_SVGA - 11'd1 + HFNPRCH_SVGA + HSYNCPW_SVGA;
+ tc_heblnk = HPIXELS_SVGA - 11'd1 + HFNPRCH_SVGA + HSYNCPW_SVGA + HBKPRCH_SVGA;
+ tc_vsblnk = VLINES_SVGA - 11'd1;
+ tc_vssync = VLINES_SVGA - 11'd1 + VFNPRCH_SVGA;
+ tc_vesync = VLINES_SVGA - 11'd1 + VFNPRCH_SVGA + VSYNCPW_SVGA;
+ tc_veblnk = VLINES_SVGA - 11'd1 + VFNPRCH_SVGA + VSYNCPW_SVGA + VBKPRCH_SVGA;
+ end
+
+ SW_XGA:
+ begin
+ hvsync_polarity = 1'b1;
+
+ tc_hsblnk = HPIXELS_XGA - 11'd1;
+ tc_hssync = HPIXELS_XGA - 11'd1 + HFNPRCH_XGA;
+ tc_hesync = HPIXELS_XGA - 11'd1 + HFNPRCH_XGA + HSYNCPW_XGA;
+ tc_heblnk = HPIXELS_XGA - 11'd1 + HFNPRCH_XGA + HSYNCPW_XGA + HBKPRCH_XGA;
+ tc_vsblnk = VLINES_XGA - 11'd1;
+ tc_vssync = VLINES_XGA - 11'd1 + VFNPRCH_XGA;
+ tc_vesync = VLINES_XGA - 11'd1 + VFNPRCH_XGA + VSYNCPW_XGA;
+ tc_veblnk = VLINES_XGA - 11'd1 + VFNPRCH_XGA + VSYNCPW_XGA + VBKPRCH_XGA;
+ end
+
+ SW_SXGA:
+ begin
+ hvsync_polarity = 1'b0; // positive polarity
+
+ tc_hsblnk = HPIXELS_SXGA - 11'd1;
+ tc_hssync = HPIXELS_SXGA - 11'd1 + HFNPRCH_SXGA;
+ tc_hesync = HPIXELS_SXGA - 11'd1 + HFNPRCH_SXGA + HSYNCPW_SXGA;
+ tc_heblnk = HPIXELS_SXGA - 11'd1 + HFNPRCH_SXGA + HSYNCPW_SXGA + HBKPRCH_SXGA;
+ tc_vsblnk = VLINES_SXGA - 11'd1;
+ tc_vssync = VLINES_SXGA - 11'd1 + VFNPRCH_SXGA;
+ tc_vesync = VLINES_SXGA - 11'd1 + VFNPRCH_SXGA + VSYNCPW_SXGA;
+ tc_veblnk = VLINES_SXGA - 11'd1 + VFNPRCH_SXGA + VSYNCPW_SXGA + VBKPRCH_SXGA;
+ end
+
+ default: //SW_HDTV720P:
+ begin
+ hvsync_polarity = 1'b0;
+
+ tc_hsblnk = HPIXELS_HDTV720P - 11'd1;
+ tc_hssync = HPIXELS_HDTV720P - 11'd1 + HFNPRCH_HDTV720P;
+ tc_hesync = HPIXELS_HDTV720P - 11'd1 + HFNPRCH_HDTV720P + HSYNCPW_HDTV720P;
+ tc_heblnk = HPIXELS_HDTV720P - 11'd1 + HFNPRCH_HDTV720P + HSYNCPW_HDTV720P + HBKPRCH_HDTV720P;
+ tc_vsblnk = VLINES_HDTV720P - 11'd1;
+ tc_vssync = VLINES_HDTV720P - 11'd1 + VFNPRCH_HDTV720P;
+ tc_vesync = VLINES_HDTV720P - 11'd1 + VFNPRCH_HDTV720P + VSYNCPW_HDTV720P;
+ tc_veblnk = VLINES_HDTV720P - 11'd1 + VFNPRCH_HDTV720P + VSYNCPW_HDTV720P + VBKPRCH_HDTV720P;
+ end
+ endcase
+ end
+
+ wire VGA_HSYNC_INT, VGA_VSYNC_INT;
+ wire [10:0] bgnd_hcount;
+ wire bgnd_hsync;
+ wire bgnd_hblnk;
+ wire [10:0] bgnd_vcount;
+ wire bgnd_vsync;
+ wire bgnd_vblnk;
+
+ timing timing_inst (
+ .tc_hsblnk(tc_hsblnk), //input
+ .tc_hssync(tc_hssync), //input
+ .tc_hesync(tc_hesync), //input
+ .tc_heblnk(tc_heblnk), //input
+ .hcount(bgnd_hcount), //output
+ .hsync(VGA_HSYNC_INT), //output
+ .hblnk(bgnd_hblnk), //output
+ .tc_vsblnk(tc_vsblnk), //input
+ .tc_vssync(tc_vssync), //input
+ .tc_vesync(tc_vesync), //input
+ .tc_veblnk(tc_veblnk), //input
+ .vcount(bgnd_vcount), //output
+ .vsync(VGA_VSYNC_INT), //output
+ .vblnk(bgnd_vblnk), //output
+ .restart(reset),
+ .clk(pclk));
+
+ /////////////////////////////////////////
+ // V/H SYNC and DE generator
+ /////////////////////////////////////////
+ assign active = !bgnd_hblnk && !bgnd_vblnk;
+
+ reg active_q;
+ reg vsync, hsync;
+ reg VGA_HSYNC, VGA_VSYNC;
+ reg de;
+
+ always @ (posedge pclk)
+ begin
+ hsync <= VGA_HSYNC_INT ^ hvsync_polarity ;
+ vsync <= VGA_VSYNC_INT ^ hvsync_polarity ;
+ VGA_HSYNC <= hsync;
+ VGA_VSYNC <= vsync;
+
+ active_q <= active;
+ de <= active_q;
+ end
+
+ ///////////////////////////////////
+ // Video pattern generator:
+ // SMPTE HD Color Bar
+ ///////////////////////////////////
+ wire [7:0] red_data, green_data, blue_data;
+
+`ifdef SIMULATION
+ reg [23:0] pixel_buffer [1279:0];
+ reg [23:0] active_pixel;
+ integer i;
+ initial begin
+ for (i = 0; i < 1280; i = i + 1) begin
+ pixel_buffer[i] = $random(dvi_tb.rx0_seed);
+ end
+
+ i = 0;
+ end
+
+ always @ (posedge pclk) begin
+ if(active_q) begin
+ active_pixel = pixel_buffer[i];
+ i = i + 1;
+ end else begin
+ i = 0;
+ active_pixel = 24'hx;
+ end
+ end
+
+ assign {red_data, green_data, blue_data} = active_pixel;
+`else
+ hdcolorbar clrbar(
+ .i_clk_74M(pclk),
+ .i_rst(reset),
+ .i_hcnt(bgnd_hcount),
+ .i_vcnt(bgnd_vcount),
+ .baronly(1'b0),
+ .i_format(2'b00),
+ .o_r(red_data),
+ .o_g(green_data),
+ .o_b(blue_data)
+ );
+`endif
+ ////////////////////////////////////////////////////////////////
+ // DVI Encoder
+ ////////////////////////////////////////////////////////////////
+ wire [4:0] tmds_data0, tmds_data1, tmds_data2;
+
+ dvi_encoder enc0 (
+ .clkin (pclk),
+ .clkx2in (pclkx2),
+ .rstin (reset),
+ .blue_din (blue_data),
+ .green_din (green_data),
+ .red_din (red_data),
+ .hsync (VGA_HSYNC),
+ .vsync (VGA_VSYNC),
+ .de (de),
+ .tmds_data0 (tmds_data0),
+ .tmds_data1 (tmds_data1),
+ .tmds_data2 (tmds_data2));
+
+
+ wire [2:0] tmdsint;
+
+ wire serdes_rst = RSTBTN | ~bufpll_lock;
+
+//`define DEBUG
+
+`ifdef DEBUG
+
+ wire [4:0] pattern = 5'b00011;
+
+ serdes_n_to_1 #(.SF(5)) oserdes0 (
+ .ioclk(pclkx10),
+ .serdesstrobe(serdesstrobe),
+ .reset(serdes_rst),
+ .gclk(pclkx2),
+ .datain(pattern),
+ .iob_data_out(tmdsint[0])) ;
+
+ serdes_n_to_1 #(.SF(5)) oserdes1 (
+ .ioclk(pclkx10),
+ .serdesstrobe(serdesstrobe),
+ .reset(serdes_rst),
+ .gclk(pclkx2),
+ .datain(pattern),
+ .iob_data_out(tmdsint[1])) ;
+
+ serdes_n_to_1 #(.SF(5)) oserdes2 (
+ .ioclk(pclkx10),
+ .serdesstrobe(serdesstrobe),
+ .reset(serdes_rst),
+ .gclk(pclkx2),
+ .datain(pattern),
+ .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])) ;
+
+`else
+ serdes_n_to_1 #(.SF(5)) oserdes0 (
+ .ioclk(pclkx10),
+ .serdesstrobe(serdesstrobe),
+ .reset(serdes_rst),
+ .gclk(pclkx2),
+ .datain(tmds_data0),
+ .iob_data_out(tmdsint[0])) ;
+
+ serdes_n_to_1 #(.SF(5)) oserdes1 (
+ .ioclk(pclkx10),
+ .serdesstrobe(serdesstrobe),
+ .reset(serdes_rst),
+ .gclk(pclkx2),
+ .datain(tmds_data1),
+ .iob_data_out(tmdsint[1])) ;
+
+ serdes_n_to_1 #(.SF(5)) oserdes2 (
+ .ioclk(pclkx10),
+ .serdesstrobe(serdesstrobe),
+ .reset(serdes_rst),
+ .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])) ;
+`endif
+
+ reg [4:0] tmdsclkint = 5'b00000;
+ reg toggle = 1'b0;
+
+ always @ (posedge pclkx2 or posedge serdes_rst) begin
+ if (serdes_rst)
+ 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 (serdes_rst),
+ .datain (tmdsclkint));
+
+ OBUFDS TMDS3 (.I(tmdsclk), .O(TMDS[3]), .OB(TMDSB[3])) ;// clock
+
+ //
+ // Debug Ports
+ //
+
+ assign DEBUG[0] = VGA_HSYNC;
+ assign DEBUG[1] = VGA_VSYNC;
+
+ // LEDs
+ assign LED = {bufpll_lock, RSTBTN, VGA_HSYNC, VGA_VSYNC} ;
+endmodule
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/ucf/dvi_demo.ucf b/fpga/spartan6/example/xapp495/dvi_demo/ucf/dvi_demo.ucf
new file mode 100644
index 0000000..4a4bb95
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/ucf/dvi_demo.ucf
@@ -0,0 +1,112 @@
+###########################################
+# Setting VCCAUX for different SP601 board
+###########################################
+CONFIG VCCAUX = 3.3;
+
+#
+# Constraint for RX0
+#
+NET "dvi_rx0/rxclk" TNM_NET = DVI_CLOCK0;
+TIMESPEC TS_DVI_CLOCK0 = PERIOD "DVI_CLOCK0" 100 MHz HIGH 50%;
+
+#
+# Constraint for RX1
+#
+NET "dvi_rx1/rxclk" TNM_NET = DVI_CLOCK1;
+TIMESPEC TS_DVI_CLOCK1 = PERIOD "DVI_CLOCK1" 100 MHz HIGH 50%;
+
+#
+# Multi-cycle paths for TX0
+#
+TIMEGRP "bramgrp_0" = RAMS(dvi_tx0/pixel2x/dataint<*>);
+TIMEGRP "fddbgrp_0" = FFS(dvi_tx0/pixel2x/db<*>);
+TIMEGRP "bramra_0" = FFS(dvi_tx0/pixel2x/ra<*>);
+
+TIMESPEC "TS_ramdo_0" = FROM "bramgrp_0" TO "fddbgrp_0" TS_DVI_CLOCK0;
+TIMESPEC "TS_ramra_0" = FROM "bramra_0" TO "fddbgrp_0" TS_DVI_CLOCK0;
+
+#
+# Multi-cycle paths for TX1
+#
+TIMEGRP "bramgrp_1" = RAMS(dvi_tx1/pixel2x/dataint<*>);
+TIMEGRP "fddbgrp_1" = FFS(dvi_tx1/pixel2x/db<*>);
+TIMEGRP "bramra_1" = FFS(dvi_tx1/pixel2x/ra<*>);
+
+TIMESPEC "TS_ramdo_1" = FROM "bramgrp_1" TO "fddbgrp_1" TS_DVI_CLOCK1;
+TIMESPEC "TS_ramra_1" = FROM "bramra_1" TO "fddbgrp_1" TS_DVI_CLOCK1;
+
+##############################################################################
+# SYSCLK Input
+##############################################################################
+NET "clk100" LOC = "L15" | IOSTANDARD = LVCMOS33 | PERIOD = 100 MHz;
+
+##############################################################################
+# Mechanical Switches (SW)
+##############################################################################
+NET "SW<0>" LOC = "A10" | IOSTANDARD = LVCMOS33 ;
+NET "SW<1>" LOC = "D14" | IOSTANDARD = LVCMOS33 ;
+#NET "SW<2>" LOC = "C14" | IOSTANDARD = LVCMOS33 ;
+#NET "SW<3>" LOC = "P15" | IOSTANDARD = LVCMOS33 ;
+
+############################################
+# TMDS pairs for Atlys top OUT: J2 - Bank 0
+############################################
+NET "TX0_TMDS(3)" LOC = "B6" |IOSTANDARD = TMDS_33 ; # Clock
+NET "TX0_TMDSB(3)" LOC = "A6" |IOSTANDARD = TMDS_33 ;
+NET "TX0_TMDS(2)" LOC = "B8" |IOSTANDARD = TMDS_33 ; # Red
+NET "TX0_TMDSB(2)" LOC = "A8" |IOSTANDARD = TMDS_33 ;
+NET "TX0_TMDS(1)" LOC = "C7" |IOSTANDARD = TMDS_33 ; # Green
+NET "TX0_TMDSB(1)" LOC = "A7" |IOSTANDARD = TMDS_33 ;
+NET "TX0_TMDS(0)" LOC = "D8" |IOSTANDARD = TMDS_33 ; # Blue
+NET "TX0_TMDSB(0)" LOC = "C8" |IOSTANDARD = TMDS_33 ;
+
+##############################################
+# TMDS pairs for Atlys top OUT: JA - Bank 2
+# Use TML_33 to add output series termination
+##############################################
+NET "TX1_TMDS(3)" LOC = "T9" |IOSTANDARD = TML_33; #TMDS_33 ; ## Clock
+NET "TX1_TMDSB(3)" LOC = "V9" |IOSTANDARD = TML_33; #TMDS_33 ; #
+NET "TX1_TMDS(2)" LOC = "N5" |IOSTANDARD = TML_33; #TMDS_33 ; ## Red
+NET "TX1_TMDSB(2)" LOC = "P6" |IOSTANDARD = TML_33; #TMDS_33 ; #
+NET "TX1_TMDS(1)" LOC = "T4" |IOSTANDARD = TML_33; #TMDS_33 ; ## Green
+NET "TX1_TMDSB(1)" LOC = "V4" |IOSTANDARD = TML_33; #TMDS_33 ; #
+NET "TX1_TMDS(0)" LOC = "R3" |IOSTANDARD = TML_33; #TMDS_33 ; ## Blue
+NET "TX1_TMDSB(0)" LOC = "T3" |IOSTANDARD = TML_33; #TMDS_33 ; #
+
+##################################################
+# TMDS pairs for Atlys IN (FPGA Bank 1): J3
+##################################################
+NET "RX1_TMDS(3)" LOC = "H17" |IOSTANDARD = TMDS_33 ; # CLK
+NET "RX1_TMDSB(3)" LOC = "H18" |IOSTANDARD = TMDS_33 ;
+NET "RX1_TMDS(2)" LOC = "J16" |IOSTANDARD = TMDS_33 ; # Red
+NET "RX1_TMDSB(2)" LOC = "J18" |IOSTANDARD = TMDS_33 ;
+NET "RX1_TMDS(1)" LOC = "L17" |IOSTANDARD = TMDS_33 ; # Green
+NET "RX1_TMDSB(1)" LOC = "L18" |IOSTANDARD = TMDS_33 ;
+NET "RX1_TMDS(0)" LOC = "K17" |IOSTANDARD = TMDS_33 ; # Blue
+NET "RX1_TMDSB(0)" LOC = "K18" |IOSTANDARD = TMDS_33 ;
+
+##############################################
+# TMDS pairs for Atlys IN (FPGA Bank 0): J1
+##############################################
+NET "RX0_TMDS(3)" LOC = "D11" |IOSTANDARD = TMDS_33 ; # CLK
+NET "RX0_TMDSB(3)" LOC = "C11" |IOSTANDARD = TMDS_33 ;
+NET "RX0_TMDS(2)" LOC = "B12" |IOSTANDARD = TMDS_33 ; # Red
+NET "RX0_TMDSB(2)" LOC = "A12" |IOSTANDARD = TMDS_33 ;
+NET "RX0_TMDS(1)" LOC = "B11" |IOSTANDARD = TMDS_33 ; # Green
+NET "RX0_TMDSB(1)" LOC = "A11" |IOSTANDARD = TMDS_33 ;
+NET "RX0_TMDS(0)" LOC = "G9" |IOSTANDARD = TMDS_33 ; # Blue
+NET "RX0_TMDSB(0)" LOC = "F9" |IOSTANDARD = TMDS_33 ;
+
+
+########################################
+# Reset button and LEDs and Mechanical Switches (SW)
+########################################
+NET "rstbtn_n" LOC = "T15" | IOSTANDARD = LVCMOS33;
+NET "LED<0>" LOC = "U18" | IOSTANDARD = LVCMOS33;
+NET "LED<1>" LOC = "M14" | IOSTANDARD = LVCMOS33;
+NET "LED<2>" LOC = "N14" | IOSTANDARD = LVCMOS33;
+NET "LED<3>" LOC = "L14" | IOSTANDARD = LVCMOS33;
+NET "LED<4>" LOC = "M13" | IOSTANDARD = LVCMOS33;
+NET "LED<5>" LOC = "D4" | IOSTANDARD = LVCMOS33;
+NET "LED<6>" LOC = "P16" | IOSTANDARD = LVCMOS33;
+NET "LED<7>" LOC = "N12" | IOSTANDARD = LVCMOS33;
diff --git a/fpga/spartan6/example/xapp495/dvi_demo/ucf/vtc_demo.ucf b/fpga/spartan6/example/xapp495/dvi_demo/ucf/vtc_demo.ucf
new file mode 100644
index 0000000..c7a94d2
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/dvi_demo/ucf/vtc_demo.ucf
@@ -0,0 +1,144 @@
+##############################################################################
+## Copyright (c) 2009 Xilinx, Inc.
+## This design is confidential and proprietary of Xilinx, All Rights Reserved.
+##############################################################################
+## ____ ____
+## / /\/ /
+## /___/ \ / Vendor: Xilinx
+## \ \ \/ Version: 1.0.0
+## \ \ Filename: vtc_demo.ucf
+## / / Date Created: April, 2009
+## /___/ /\
+## \ \ / \
+## \___\/\___\
+##
+## Devices: Spartan-36Generation FPGA
+## Purpose: Constraint file for programmable video timing controller
+## Contact: bob.feng@xilinx.com
+## Reference: None
+##
+## Revision History:
+##
+##
+##############################################################################
+##
+## LIMITED WARRANTY AND DISCLAIMER. 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 warrant or 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 (c) 2009 Xilinx, Inc.
+## This design is confidential and proprietary of Xilinx, All Rights Reserved.
+##############################################################################
+
+###########################################
+# Setting VCCAUX for different SP601 board
+###########################################
+VCCAUX = 3.3;
+
+########################################
+# Reset button and LEDs
+########################################
+NET "RSTBTN" LOC = "N4";
+NET "LED<0>" LOC = "H12";
+NET "LED<1>" LOC = "G13";
+NET "LED<2>" LOC = "E16";
+NET "LED<3>" LOC = "E18";
+
+##############################################################################
+# SYSCLK Input
+##############################################################################
+
+NET "SYS_CLK" LOC = "L15";
+
+##############################################################################
+# Mechanical Switches (SW)
+##############################################################################
+
+NET "SW<0>" LOC = "A10" | IOSTANDARD = LVCMOS33 ;
+NET "SW<1>" LOC = "D14" | IOSTANDARD = LVCMOS33 ;
+NET "SW<2>" LOC = "C14" | IOSTANDARD = LVCMOS33 ;
+NET "SW<3>" LOC = "P15" | IOSTANDARD = LVCMOS33 ;
+
+##############################################################################
+# Debug Port # JA1
+##############################################################################
+NET "DEBUG[0]" LOC = "B12" | IOSTANDARD = LVCMOS33;
+NET "DEBUG[1]" LOC = "B11" | IOSTANDARD = LVCMOS33;
+
+##############################################################################
+# DCM/PLL/BUFPLL positions
+##############################################################################
+#INST "PCLK_GEN_INST" LOC = "DCM_X0Y3";
+#INST "PLL_OSERDES" LOC = "PLL_ADV_X0Y1";
+#INST "ioclk_buf" LOC = "BUFPLL_X1Y0";
+
+###########################################
+# Timing Constraints
+###########################################
+NET "clk50m_bufg" TNM_NET = "TNM_CLK50M";
+TIMESPEC "TS_CLK50M" = PERIOD "TNM_CLK50M" 50 MHz HIGH 50 % PRIORITY 0 ;
+
+NET "pclk" TNM_NET = "TNM_PCLK";
+TIMESPEC "TS_PCLK" = PERIOD "TNM_PCLK" 108 MHz HIGH 50 % PRIORITY 0 ;
+
+NET "pclkx2" TNM_NET = "TNM_PCLKX2";
+TIMESPEC "TS_PCLKX2" = PERIOD "TNM_PCLKX2" TS_PCLK * 2;
+
+NET "pclkx10" TNM_NET = "TNM_PCLKX10";
+TIMESPEC "TS_PCLKX10" = PERIOD "TNM_PCLKX10" TS_PCLK * 10;
+
+#
+# Multi-cycle paths
+#
+TIMEGRP "bramgrp" = RAMS(enc0/pixel2x/dataint<*>);
+TIMEGRP "fddbgrp" = FFS(enc0/pixel2x/db<*>);
+TIMEGRP "bramra" = FFS(enc0/pixel2x/ra<*>);
+
+TIMESPEC "TS_ramdo" = FROM "bramgrp" TO "fddbgrp" TS_PCLK;
+TIMESPEC "TS_ramra" = FROM "bramra" TO "fddbgrp" TS_PCLK;
+
+############################
+# TMDS pairs on the top
+############################
+#NET "TMDS(0)" LOC = "C7" | IOSTANDARD = TMDS_33 ; # Blue
+#NET "TMDSB(0)" LOC = "A7" | IOSTANDARD = TMDS_33 ;
+#NET "TMDS(1)" LOC = "D8" | IOSTANDARD = TMDS_33 ; # Red
+#NET "TMDSB(1)" LOC = "C8" | IOSTANDARD = TMDS_33 ;
+#NET "TMDS(2)" LOC = "B6" | IOSTANDARD = TMDS_33 ; # Green
+#NET "TMDSB(2)" LOC = "A6" | IOSTANDARD = TMDS_33 ;
+#NET "TMDS(3)" LOC = "B8" | IOSTANDARD = TMDS_33 ; # Clock
+#NET "TMDSB(3)" LOC = "A8" | IOSTANDARD = TMDS_33 ;
+
+NET "TMDS(0)" LOC = "D8" | IOSTANDARD = TMDS_33 ; # Blue
+NET "TMDSB(0)" LOC = "C8" | IOSTANDARD = TMDS_33 ;
+NET "TMDS(1)" LOC = "C7" | IOSTANDARD = TMDS_33 ; # Red
+NET "TMDSB(1)" LOC = "A7" | IOSTANDARD = TMDS_33 ;
+NET "TMDS(2)" LOC = "B8" | IOSTANDARD = TMDS_33 ; # Green
+NET "TMDSB(2)" LOC = "A8" | IOSTANDARD = TMDS_33 ;
+NET "TMDS(3)" LOC = "B6" | IOSTANDARD = TMDS_33 ; # Clock
+NET "TMDSB(3)" LOC = "A6" | IOSTANDARD = TMDS_33 ;
+
+
+
+
+
+
+
+##############################################################################
diff --git a/fpga/spartan6/example/xapp495/readme.txt b/fpga/spartan6/example/xapp495/readme.txt
new file mode 100755
index 0000000..5cc5c43
--- /dev/null
+++ b/fpga/spartan6/example/xapp495/readme.txt
@@ -0,0 +1,102 @@
+*******************************************************************************
+** © Copyright 2010 Xilinx, Inc. All rights reserved.
+** This file contains confidential and proprietary information of Xilinx, Inc. and
+** is protected under U.S. and international copyright and other intellectual property laws.
+*******************************************************************************
+** ____ ____
+** / /\/ /
+** /___/ \ / Vendor: Xilinx
+** \ \ \/
+** \ \ readme.txt Version: 1.0
+** / / Date Last Modified: 11/17/2010
+** /___/ /\ Date Created:
+** \ \ / \ Associated Filename: xapp495.zip
+** \___\/\___\
+**
+** Device:
+** Purpose:
+** Reference: XAPP495.pdf
+** Revision History:
+** 1.0 - Initial Release
+**
+*******************************************************************************
+**
+** Disclaimer:
+**
+** This disclaimer is not a license and does not grant any rights to the materials
+** distributed herewith. Except as otherwise provided in a valid license issued to you
+** by Xilinx, and to the maximum extent permitted by applicable law:
+** (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS,
+** AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
+** INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR
+** FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable (whether in contract
+** or tort, including negligence, or under any other theory of liability) for any loss or damage
+** of any kind or nature related to, arising under or in connection with these materials,
+** including for any direct, or any indirect, special, incidental, or consequential loss
+** or damage (including loss of data, profits, goodwill, or any type of loss or damage suffered
+** as a result of any action brought by a third party) even if such damage or loss was
+** reasonably foreseeable or Xilinx had been advised of the possibility of the same.
+
+
+** Critical Applications:
+**
+** Xilinx products are not designed or intended to be fail-safe, or for use in any application
+** requiring fail-safe performance, such as life-support or safety devices or systems,
+** Class III medical devices, nuclear facilities, applications related to the deployment of airbags,
+** or any other applications that could lead to death, personal injury, or severe property or
+** environmental damage (individually and collectively, "Critical Applications"). Customer assumes
+** the sole risk and liability of any use of Xilinx products in Critical Applications, subject only
+** to applicable laws and regulations governing limitations on product liability.
+
+** THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
+
+*******************************************************************************
+
+This readme describes how to use the files that come with XAPP495
+
+*******************************************************************************
+
+** IMPORTANT NOTES **
+
+1) The design files have been tested on Digilent Atlys Board
+
+2) The UCF files are targeted to the Atlys board
+
+*******************************************************************************
+
+Included files:
+
+DVI transmitter
+
+1. "dvi_demo/rtl/tx/dvi_encoder.v" --- DVI transmitter top module without instantiation of clocking resources
+2. "dvi_demo/rtl/tx/dvi_encoder_top.v" --- DVI transmitter wrapper with instantiation of clocking resources
+3. "dvi_demo/rtl/tx/encode.v" --- DVI encoder
+4. "dvi_demo/rtl/tx/serdes_n_to_1.v" --- configurable to 5:1 serializaer
+5. "dvi_demo/rtl/tx/convert_30to15_fifo.v" --- 30-bit 2:1 gear box
+6. "dvi_demo/rtl/tx/vtc_demo.v" --- Color bar generator with programmable timing controller
+
+DVI Receiver
+
+1. "dvi_demo/rtl/tx/dvi_decoder.v" --- DVI receiver top wrapper
+2. "dvi_demo/rtl/tx/decode.v" --- DVI decoder instantiating the CDR and channel de-skew circuits
+3. "dvi_demo/rtl/tx/chnlbond.v" --- Channel de-skew module
+4. "dvi_demo/rtl/tx/phsaligner.v" --- Bitslip and TMDS data validation state machine
+5. "dvi_demo/rtl/tx/serdes_1_to_5_diff_data.v" --- 1:5 de-serializer
+
+DVI Common Modules
+
+1. "dvi_demo/rtl/common/DRAM16XN.v" --- Width configurable distributed RAM
+2. "dvi_demo/rtl/common/timing.v" --- Video Timing Controller
+3. "dvi_demo/rtl/common/hdclrbar.v" --- SMPTE HD color bar generator
+4. "dvi_demo/rtl/common/debnce.v" --- DIP switch debouncer
+5. "dvi_demo/rtl/common/dcmspi.v" --- DCM_CLKGEN SPI controller
+6. "dvi_demo/rtl/common/synchro.v" --- Clock boundary synchronizer
+
+DVI Evaluation
+
+"dvi_demo/rtl/dvi_demo.v" --- 2x2 DVI Matrix design
+
+UCF
+
+"dvi_demo/ucf/vtc_demo.ucf" --- Transmitter only design with color bar generation and programmable timing controller
+"dvi_demo/ucf/dvi_demo.ucf" --- 2x2 DVI Matrix design