www.pudn.com > dvi_demo.rar > dvi_demo.v, change:2008-07-24,size:13116b


////////////////////////////////////////////////////////////////////////////// 
// Copyright (c) 2006 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. 2008 
// /___/   /\    Last Modified: Feb. 2008 
// \   \  /  \ 
//  \___\/\___\ 
// 
// Devices:   Spartan-3A  FPGA 
// Purpose:   DVI Pass Through Top Module 
// Contact:    
// Reference: None 
// 
// Revision History: 
//   Rev 1.0.0 - (Bob Feng) First created Feb. 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 
 
//`define DIRECTPASS 
 
module dvi_demo ( 
  input  wire       CLK_74M_I, 
  input wire [3:0]  RX_TMDS, 
  input wire [3:0]  RX_TMDSB, 
 
  input  wire       j7_option, 
  input  wire       j8_option, 
 
  output wire       tx_oe_n, 
  output wire       tx_pre, 
  output wire       rx_oe_n, 
  output wire       rx_pre, 
 
  output wire       LED, 
 
  output wire [3:0] TX_TMDS, 
  output wire [3:0] TX_TMDSB 
); 
 
  parameter SW_HDTV720P   = 2'b00; 
  parameter SW_HDTV1080I  = 2'b01; 
 
  assign tx_oe_n = j7_option; 
  assign tx_pre  = j8_option; 
  assign rx_oe_n = j7_option; 
  assign rx_pre  = j8_option; 
 
  //******************************************************************// 
  // Create global clock and synchronous system reset.                // 
  //******************************************************************// 
  wire          clkin; 
  wire          clk; 
  wire          clkx5; 
  wire          clkx5not; 
 
  BUFG   stbclk_bufg (.I(CLK_74M_I), .O(clkin)); 
 
  wire rx_hsync;          // hsync data 
  wire rx_vsync;          // vsync data 
  wire rx_de;             // data enable 
  wire rx_psalgnerr;      // channel phase alignment error 
  wire [7:0] rx_red;      // pixel data out 
  wire [7:0] rx_green;    // pixel data out 
  wire [7:0] rx_blue;     // pixel data out 
  wire [29:0] rx_sdata; 
 
  dvi_decoder # ( 
    .TMDS_INVERT ("TRUE") 
  ) dvi_rx0 ( 
    //These are input ports 
    .clkin       (clkin), 
    .tmdsclk_p   (RX_TMDS[3]), 
    .tmdsclk_n   (RX_TMDSB[3]), 
    .blue_p      (RX_TMDS[0]), 
    .green_p     (RX_TMDS[1]), 
    .red_p       (RX_TMDS[2]), 
    .blue_n      (RX_TMDSB[0]), 
    .green_n     (RX_TMDSB[1]), 
    .red_n       (RX_TMDSB[2]), 
 
    //These are output ports 
    .clk         (clk), 
    .clkx5       (clkx5), 
    .clkx5not    (clkx5not), 
    .reset       (reset), 
    .hsync       (rx_hsync), 
    .vsync       (rx_vsync), 
    .de          (rx_de), 
    .psalgnerr   (rx_psalgnerr), 
    .sdout       (rx_sdata), 
    .red         (rx_red), 
    .green       (rx_green), 
    .blue        (rx_blue));  
 
  // TMDS output 
  wire         tx_de = rx_de; 
  wire [3:0]   TMDSINT ; 
  wire [7:0]   tmds_data ; 
 
  wire [7:0]   red_data, green_data, blue_data; 
 
 
`ifdef DIRECTPASS 
  reg [29:0] rx_sdata_q; 
 
  //Using NEKO daugther card 
  //Polarity is inverted 
  always @ (posedge clk) begin 
    rx_sdata_q <= ~rx_sdata; 
  end 
 
  serdes_4b_10to1 serialise ( 
    .clk      (clk), 
    .clkx5    (clkx5), 
    .clkx5not (clkx5not), 
    .datain   (rx_sdata_q), 
    .rst      (reset), 
    .dataout  (tmds_data)) ; 
 
`else 
  dvi_encoder # ( 
    .SDATAINVERT("TRUE") 
  ) dvi_tx0 ( 
    .clkin			(clk), 
    .clkx5in		(clkx5), 
    .clkx5notin	(clkx5not), 
    .rstin			(reset), 
    .blue_din		(blue_data), 
    .green_din	(green_data), 
    .red_din		(red_data), 
    .hsync			(rx_hsync), 
    .vsync			(rx_vsync), 
    .de			    (tx_de), 
    .tmds_data	(tmds_data)); 
`endif 
 
  ODDR2 #(.DDR_ALIGNMENT("NONE")) ddr_reg0 (.C0(clkx5),  
                                            .C1(clkx5not),  
                                            .D0(tmds_data[0]),  
                                            .D1(tmds_data[4]),  
                                            .CE(1'b1),  
                                            .R(1'b0),  
                                            .S(1'b0),  
                                            .Q(TMDSINT[0])) ; 
 
  ODDR2 #(.DDR_ALIGNMENT("NONE")) ddr_reg1 (.C0(clkx5),  
                                            .C1(clkx5not),  
                                            .D0(tmds_data[1]),  
                                            .D1(tmds_data[5]),  
                                            .CE(1'b1),  
                                            .R(1'b0),  
                                            .S(1'b0),  
                                            .Q(TMDSINT[1])) ; 
 
  ODDR2 #(.DDR_ALIGNMENT("NONE")) ddr_reg2 (.C0(clkx5),  
                                            .C1(clkx5not),  
                                            .D0(tmds_data[2]),  
                                            .D1(tmds_data[6]),  
                                            .CE(1'b1),  
                                            .R(1'b0),  
                                            .S(1'b0),  
                                            .Q(TMDSINT[2])) ; 
 
  ODDR2 #(.DDR_ALIGNMENT("NONE")) ddr_reg3 (.C0(clkx5),        //C0(clk), 
                                            .C1(clkx5not),     //C1(~clk), 
                                            .D0(tmds_data[3]), //D0(1'b0), 
                                            .D1(tmds_data[7]), //D1(1'b1), 
                                            .CE(1'b1),  
                                            .R(1'b0),  
                                            .S(1'b0),  
                                            .Q(TMDSINT[3])) ; 
 
  OBUFDS TMDS0 (.I(TMDSINT[0]), .O(TX_TMDS[0]), .OB(TX_TMDSB[0])) ; 
  OBUFDS TMDS1 (.I(TMDSINT[1]), .O(TX_TMDS[1]), .OB(TX_TMDSB[1])) ; 
  OBUFDS TMDS2 (.I(TMDSINT[2]), .O(TX_TMDS[2]), .OB(TX_TMDSB[2])) ; 
  OBUFDS TMDS3 (.I(TMDSINT[3]), .O(TX_TMDS[3]), .OB(TX_TMDSB[3])) ;// clock 
			 
 
  ////////////////////////////////////// 
  // Status LED 
  ////////////////////////////////////// 
  assign LED = rx_psalgnerr; 
 
  /////////////////////////////////////////////////////////// 
  // Flying Logo: Spartan3A Logo flying  
  /////////////////////////////////////////////////////////// 
  wire VGA_VSYNC = rx_vsync; 
  wire VGA_HSYNC = rx_hsync; 
  wire pclk = clk; 
 
  ////////////////////////////////////////// 
  // Here I create a vcounter and hcounter 
  ////////////////////////////////////////// 
  reg hsync_q, linestart; 
  always @ (posedge pclk) begin 
    hsync_q <=#1 VGA_HSYNC; 
    linestart <=#1 !hsync_q & VGA_HSYNC;  
  end 
   
  reg vsync_q, framestart; 
  always @ (posedge pclk) begin 
    vsync_q <= VGA_VSYNC;  
    framestart <= !vsync_q & VGA_VSYNC; 
  end 
   
  reg twoframes; 
  always @ (posedge pclk) begin 
    if(reset) 
      twoframes <= 1'b0; 
    else if(framestart) 
      twoframes <= ~twoframes; 
  end 
 
  reg twoframes_q, dblframe; 
  always @ (posedge pclk) begin 
    twoframes_q <= twoframes; 
    dblframe <= !twoframes_q & twoframes; 
  end 
 
  // 
  // Here I am simply trying to hold the logo for 2 seconds which consume about 120 frames 
  // 
  reg [7:0] timestep; 
  wire tstep_mid; 
 
  assign tstep_mid = (timestep == (8'd78 >> 1)); 
 
  reg tstep_mid_q; 
  reg hldlogo_cnt_rst; 
  reg [7:0] hldlogo_cnt; //a counter to hold logo on the top (when timestep is 78) 
  wire hldlogo_cnt_full; 
 
  always @ (posedge pclk) begin 
    tstep_mid_q <= tstep_mid; 
    hldlogo_cnt_rst <= !tstep_mid_q & tstep_mid; 
  end 
 
  always @ (posedge pclk) begin 
    if(hldlogo_cnt_rst) 
      hldlogo_cnt <= 8'h0; 
    else if(framestart && !hldlogo_cnt_full) 
      hldlogo_cnt <= hldlogo_cnt + 1'b1; 
  end 
 
  assign hldlogo_cnt_full = (hldlogo_cnt == 8'hff); 
 
  wire hldlogo; 
  assign hldlogo = (tstep_mid && !hldlogo_cnt_full); 
 
   always @ (posedge pclk) begin 
    if(reset) 
      timestep <= 8'h0; 
    //else if(dblframe && !hldlogo) 
    else if(framestart && !hldlogo) 
      timestep <= timestep + 1'b1; 
  end 
 
  parameter BLACK  = {8'h0, 8'h0, 8'h0}; 
  parameter WHITE  = {8'hff, 8'hff, 8'hff}; 
  parameter YELLOW = {8'hff, 8'hff, 8'h0}; 
  parameter RED    = {8'hff, 8'h0, 8'h0}; 
  parameter GREEN  = {8'h0, 8'hff, 8'h0}; 
  parameter TRANSP = GREEN; 
 
  parameter LOGO_WIDTH  = 12'd128; 
  parameter LOGO_HEIGHT = 12'd128; 
 
  wire   [11:0] auto_data_x; 
  wire   [11:0] auto_data_y; 
 
  autopilot autopilot_inst ( //ROM stores logo starting position 
    .timestep({timestep[6:0], 1'b0}), //shift left to make it 2x faster 
    .xlocation(auto_data_x), 
    .ylocation(auto_data_y), 
    .clk(pclk)); 
 
  reg    [11:0] cursor2_xidx; 
  reg    [11:0] cursor2_yidx; 
  wire    [1:0] cursor2_data; 
  wire          cursor2_mask; 
 
  reg    [11:0] cursor3_xidx; 
  reg    [11:0] cursor3_yidx; 
  wire    [1:0] cursor3_data; 
  wire          cursor3_mask; 
 
  reg     [7:0] cursor2_r; 
  reg     [7:0] cursor2_g; 
  reg     [7:0] cursor2_b; 
  reg           cursor2_t; 
 
  ////////////////////////////////////////// 
  // naive hcounter and vcounter 
  ////////////////////////////////////////// 
  reg    [11:0] bgnd_hcount, bgnd_vcount; 
  always @ (posedge pclk) begin 
    if(linestart) 
      bgnd_hcount <=#1 12'h0; 
    else if(tx_de) 
      bgnd_hcount <=#1 bgnd_hcount + 1'b1; 
  end 
 
  always @ (posedge pclk) begin 
    if(framestart) 
      bgnd_vcount <=#1 12'h0; 
    else if(linestart) 
      bgnd_vcount <=#1 bgnd_vcount + 1'b1; 
  end 
 
  wire    [11:0] hcount_hwc2_pipe = bgnd_hcount; 
  wire    [11:0] vcount_hwc2_pipe = bgnd_vcount; 
  //always @(posedge pclk) hcount_hwc2_pipe <= bgnd_hcount; 
  //always @(posedge pclk) vcount_hwc2_pipe <= bgnd_vcount; 
 
  always @(posedge pclk) cursor2_xidx <= hcount_hwc2_pipe - auto_data_x; //cursor2_xpos; 
  always @(posedge pclk) cursor2_yidx <= vcount_hwc2_pipe - auto_data_y; //cursor2_ypos; 
  always @(posedge pclk) cursor3_xidx <= 12'h0; //hcount_hwc2_pipe - cursor3_xpos; 
  always @(posedge pclk) cursor3_yidx <= 12'h0; //vcount_hwc2_pipe - cursor3_ypos; 
 
  cursor_pair #(.IMAGE("SPARTAN3A")) 
  cursor_pair_inst1 ( 
    .xidx0(cursor2_xidx), 
    .yidx0(cursor2_yidx), 
    .data0(cursor2_data), 
    .mask0(cursor2_mask), 
    .xidx1(cursor3_xidx), 
    .yidx1(cursor3_yidx), 
    .data1(cursor3_data), 
    .mask1(cursor3_mask), 
    .clk(pclk)); 
 
  always @(posedge pclk) 
  begin 
    if (cursor2_mask) 
    begin 
      cursor2_r <= 4'h0; 
      cursor2_g <= 4'h0; 
      cursor2_b <= 4'h0; 
      cursor2_t <= 1'b1; 
    end 
    else 
    begin 
      case (cursor2_data) 
      0: begin 
           {cursor2_r, cursor2_g, cursor2_b} <= TRANSP; 
           cursor2_t <=  1'b1; 
         end 
      1: begin 
           {cursor2_r, cursor2_g, cursor2_b} <= YELLOW; 
           cursor2_t <= 1'b0; 
         end 
      2: begin 
           {cursor2_r, cursor2_g, cursor2_b} <= RED; 
           cursor2_t <= 1'b0; 
         end 
      3: begin 
           {cursor2_r, cursor2_g, cursor2_b} <= BLACK; 
           cursor2_t <= 1'b0; 
         end 
      endcase 
    end 
  end 
 
  assign red_data   = (cursor2_t) ? rx_red   : cursor2_r; 
  assign green_data = (cursor2_t) ? rx_green : cursor2_g; 
  assign blue_data  = (cursor2_t) ? rx_blue  : cursor2_b; 
 
endmodule