之前记录过赛灵思高速收发器的一些基础知识和ip的使用方法,但一直没有在开发板上进行验证,今天利用HDMI输出视频经过光口回环之后在显示屏上进行显示。首先生成GTX的ip核具体配置如下图所示:
然后生成官方例程,具体方法如下图所示:
然后对例程的顶层模块进行更改,变成如下的形式
需要注意的是数据在经过光口传输之后很可能出现乱码的情况,因此我们需要对数据进行编解码后再进行数据对齐。将顶层模块做如下修改:
// ____ ____
// / /\/ /
// /___/ \ / Vendor: Xilinx
// \ \ \/ Version : 3.6
// \ \ Application : 7 Series FPGAs Transceivers Wizard
// / / Filename : gtwizard_0_exdes.v
// /___/ /\
// \ \ / \
// \___\/\___\
//
//
// Module gtwizard_0_exdes
// Generated by Xilinx 7 Series FPGAs Transceivers Wizard
//
//
// (c) Copyright 2010-2012 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.
//
// 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 1ns / 1ps
`define DLY #1
(* DowngradeIPIdentifiedWarnings="yes" *)
//***********************************Entity Declaration************************
(* CORE_GENERATION_INFO = "gtwizard_0,gtwizard_v3_6_13,{protocol_file=aurora_8b10b_single_lane_4byte}" *)
module gtwizard_0_exdes
(
input wire GTREFCLK_PAD_N_IN,
input wire GTREFCLK_PAD_P_IN,
input wire drp_clk,
output tx0_clk ,
input [31:0] tx0_data ,
input [3 :0] tx0_kchar ,
output rx0_clk ,
output [31:0] rx0_data ,
output [3 :0] rx0_kchar ,
output gt0_tx_system_rstn ,
output gt0_rx_system_rstn ,
output tx1_clk ,
input [31:0] tx1_data ,
input [3 :0] tx1_kchar ,
output rx1_clk ,
output [31:0] rx1_data ,
output [3 :0] rx1_kchar ,
output gt1_tx_system_rstn ,
output gt1_rx_system_rstn ,
input wire [1:0] RXN_IN,
input wire [1:0] RXP_IN,
output wire [1:0] TXN_OUT,
output wire [1:0] TXP_OUT
);
wire soft_reset_i;
(*mark_debug = "TRUE" *) wire soft_reset_vio_i;
//************************** Register Declarations ****************************
wire gt_txfsmresetdone_i;
wire gt_rxfsmresetdone_i;
(* ASYNC_REG = "TRUE" *)reg gt_txfsmresetdone_r;
(* ASYNC_REG = "TRUE" *)reg gt_txfsmresetdone_r2;
wire gt0_txfsmresetdone_i;
wire gt0_rxfsmresetdone_i;
(* ASYNC_REG = "TRUE" *)reg gt0_txfsmresetdone_r;
(* ASYNC_REG = "TRUE" *)reg gt0_txfsmresetdone_r2;
(* ASYNC_REG = "TRUE" *)reg gt0_rxfsmresetdone_r;
(* ASYNC_REG = "TRUE" *)reg gt0_rxfsmresetdone_r2;
(* ASYNC_REG = "TRUE" *)reg gt0_rxresetdone_r;
(* ASYNC_REG = "TRUE" *)reg gt0_rxresetdone_r2;
(* ASYNC_REG = "TRUE" *)reg gt0_rxresetdone_r3;
(* ASYNC_REG = "TRUE" *)reg gt0_rxresetdone_vio_r;
(* ASYNC_REG = "TRUE" *)reg gt0_rxresetdone_vio_r2;
(* ASYNC_REG = "TRUE" *)reg gt0_rxresetdone_vio_r3;
wire gt1_txfsmresetdone_i;
wire gt1_rxfsmresetdone_i;
(* ASYNC_REG = "TRUE" *)reg gt1_txfsmresetdone_r;
(* ASYNC_REG = "TRUE" *)reg gt1_txfsmresetdone_r2;
(* ASYNC_REG = "TRUE" *)reg gt1_rxfsmresetdone_r;
(* ASYNC_REG = "TRUE" *)reg gt1_rxfsmresetdone_r2;
(* ASYNC_REG = "TRUE" *)reg gt1_rxresetdone_r;
(* ASYNC_REG = "TRUE" *)reg gt1_rxresetdone_r2;
(* ASYNC_REG = "TRUE" *)reg gt1_rxresetdone_r3;
(* ASYNC_REG = "TRUE" *)reg gt1_rxresetdone_vio_r;
(* ASYNC_REG = "TRUE" *)reg gt1_rxresetdone_vio_r2;
(* ASYNC_REG = "TRUE" *)reg gt1_rxresetdone_vio_r3;
reg [5:0] reset_counter = 0;
reg [3:0] reset_pulse;
//**************************** Wire Declarations ******************************//
//------------------------ GT Wrapper Wires ------------------------------
//________________________________________________________________________
//________________________________________________________________________
//GT0 (X1Y12)
//-------------------------- Channel - DRP Ports --------------------------
wire [8:0] gt0_drpaddr_i;
wire [15:0] gt0_drpdi_i;
wire [15:0] gt0_drpdo_i;
wire gt0_drpen_i;
wire gt0_drprdy_i;
wire gt0_drpwe_i;
//------------------------- Digital Monitor Ports --------------------------
wire [7:0] gt0_dmonitorout_i;
//----------------------------- Loopback Ports -----------------------------
wire [2:0] gt0_loopback_i;
//---------------------------- Power-Down Ports ----------------------------
wire [1:0] gt0_rxpd_i;
wire [1:0] gt0_txpd_i;
//------------------- RX Initialization and Reset Ports --------------------
wire gt0_eyescanreset_i;
wire gt0_rxuserrdy_i;
//------------------------ RX Margin Analysis Ports ------------------------
wire gt0_eyescandataerror_i;
wire gt0_eyescantrigger_i;
//----------------------- Receive Ports - CDR Ports ------------------------
wire gt0_rxcdrhold_i;
wire gt0_rxcdrovrden_i;
//----------------- Receive Ports - Clock Correction Ports -----------------
wire [1:0] gt0_rxclkcorcnt_i;
//---------------- Receive Ports - FPGA RX interface Ports -----------------
wire [31:0] gt0_rxdata_i;
//----------------- Receive Ports - Pattern Checker Ports ------------------
wire gt0_rxprbserr_i;
wire [2:0] gt0_rxprbssel_i;
//----------------- Receive Ports - Pattern Checker ports ------------------
wire gt0_rxprbscntreset_i;
//---------------- Receive Ports - RX 8B/10B Decoder Ports -----------------
wire [3:0] gt0_rxdisperr_i;
wire [3:0] gt0_rxnotintable_i;
//------------------------- Receive Ports - RX AFE -------------------------
wire gt0_gtxrxp_i;
//---------------------- Receive Ports - RX AFE Ports ----------------------
wire gt0_gtxrxn_i;
//----------------- Receive Ports - RX Buffer Bypass Ports -----------------
wire gt0_rxbufreset_i;
wire [2:0] gt0_rxbufstatus_i;
//------------ Receive Ports - RX Byte and Word Alignment Ports ------------
wire gt0_rxbyteisaligned_i;
wire gt0_rxbyterealign_i;
wire gt0_rxcommadet_i;
wire gt0_rxmcommaalignen_i;
wire gt0_rxpcommaalignen_i;
//------------------- Receive Ports - RX Equalizer Ports -------------------
wire gt0_rxdfelpmreset_i;
wire [6:0] gt0_rxmonitorout_i;
wire [1:0] gt0_rxmonitorsel_i;
//------------- Receive Ports - RX Fabric Output Control Ports -------------
wire gt0_rxoutclk_i;
wire gt0_rxoutclkfabric_i;
//----------- Receive Ports - RX Initialization and Reset Ports ------------
wire gt0_gtrxreset_i;
wire gt0_rxpcsreset_i;
wire gt0_rxpmareset_i;
//---------------- Receive Ports - RX Margin Analysis ports ----------------
wire gt0_rxlpmen_i;
//--------------- Receive Ports - RX Polarity Control Ports ----------------
wire gt0_rxpolarity_i;
//----------------- Receive Ports - RX8B/10B Decoder Ports -----------------
wire [3:0] gt0_rxchariscomma_i;
wire [3:0] gt0_rxcharisk_i;
//------------ Receive Ports -RX Initialization and Reset Ports ------------
wire gt0_rxresetdone_i;
//---------------------- TX Configurable Driver Ports ----------------------
wire [4:0] gt0_txpostcursor_i;
wire [4:0] gt0_txprecursor_i;
//------------------- TX Initialization and Reset Ports --------------------
wire gt0_gttxreset_i;
wire gt0_txuserrdy_i;
//-------------- Transmit Ports - 8b10b Encoder Control Ports --------------
wire [3:0] gt0_txchardispmode_i;
wire [3:0] gt0_txchardispval_i;
//---------------- Transmit Ports - Pattern Generator Ports ----------------
wire gt0_txprbsforceerr_i;
//-------------------- Transmit Ports - TX Buffer Ports --------------------
wire [1:0] gt0_txbufstatus_i;
//------------- Transmit Ports - TX Configurable Driver Ports --------------
wire [3:0] gt0_txdiffctrl_i;
wire [6:0] gt0_txmaincursor_i;
//---------------- Transmit Ports - TX Data Path interface -----------------
wire [31:0] gt0_txdata_i;
//-------------- Transmit Ports - TX Driver and OOB signaling --------------
wire gt0_gtxtxn_i;
wire gt0_gtxtxp_i;
//--------- Transmit Ports - TX Fabric Clock Output Control Ports ----------
wire gt0_txoutclk_i;
wire gt0_txoutclkfabric_i;
wire gt0_txoutclkpcs_i;
//------------------- Transmit Ports - TX Gearbox Ports --------------------
wire [3:0] gt0_txcharisk_i;
//----------- Transmit Ports - TX Initialization and Reset Ports -----------
wire gt0_txpcsreset_i;
wire gt0_txpmareset_i;
wire gt0_txresetdone_i;
//--------------- Transmit Ports - TX Polarity Control Ports ---------------
wire gt0_txpolarity_i;
//---------------- Transmit Ports - pattern Generator Ports ----------------
wire [2:0] gt0_txprbssel_i;
//________________________________________________________________________
//________________________________________________________________________
//GT1 (X1Y13)
//-------------------------- Channel - DRP Ports --------------------------
wire [8:0] gt1_drpaddr_i;
wire [15:0] gt1_drpdi_i;
wire [15:0] gt1_drpdo_i;
wire gt1_drpen_i;
wire gt1_drprdy_i;
wire gt1_drpwe_i;
//------------------------- Digital Monitor Ports --------------------------
wire [7:0] gt1_dmonitorout_i;
//----------------------------- Loopback Ports -----------------------------
wire [2:0] gt1_loopback_i;
//---------------------------- Power-Down Ports ----------------------------
wire [1:0] gt1_rxpd_i;
wire [1:0] gt1_txpd_i;
//------------------- RX Initialization and Reset Ports --------------------
wire gt1_eyescanreset_i;
wire gt1_rxuserrdy_i;
//------------------------ RX Margin Analysis Ports ------------------------
wire gt1_eyescandataerror_i;
wire gt1_eyescantrigger_i;
//----------------------- Receive Ports - CDR Ports ------------------------
wire gt1_rxcdrhold_i;
wire gt1_rxcdrovrden_i;
//----------------- Receive Ports - Clock Correction Ports -----------------
wire [1:0] gt1_rxclkcorcnt_i;
//---------------- Receive Ports - FPGA RX interface Ports -----------------
wire [31:0] gt1_rxdata_i;
//----------------- Receive Ports - Pattern Checker Ports ------------------
wire gt1_rxprbserr_i;
wire [2:0] gt1_rxprbssel_i;
//----------------- Receive Ports - Pattern Checker ports ------------------
wire gt1_rxprbscntreset_i;
//---------------- Receive Ports - RX 8B/10B Decoder Ports -----------------
wire [3:0] gt1_rxdisperr_i;
wire [3:0] gt1_rxnotintable_i;
//------------------------- Receive Ports - RX AFE -------------------------
wire gt1_gtxrxp_i;
//---------------------- Receive Ports - RX AFE Ports ----------------------
wire gt1_gtxrxn_i;
//----------------- Receive Ports - RX Buffer Bypass Ports -----------------
wire gt1_rxbufreset_i;
wire [2:0] gt1_rxbufstatus_i;
//------------ Receive Ports - RX Byte and Word Alignment Ports ------------
wire gt1_rxbyteisaligned_i;
wire gt1_rxbyterealign_i;
wire gt1_rxcommadet_i;
wire gt1_rxmcommaalignen_i;
wire gt1_rxpcommaalignen_i;
//------------------- Receive Ports - RX Equalizer Ports -------------------
wire gt1_rxdfelpmreset_i;
wire [6:0] gt1_rxmonitorout_i;
wire [1:0] gt1_rxmonitorsel_i;
//------------- Receive Ports - RX Fabric Output Control Ports -------------
wire gt1_rxoutclk_i;
wire gt1_rxoutclkfabric_i;
//----------- Receive Ports - RX Initialization and Reset Ports ------------
wire gt1_gtrxreset_i;
wire gt1_rxpcsreset_i;
wire gt1_rxpmareset_i;
//---------------- Receive Ports - RX Margin Analysis ports ----------------
wire gt1_rxlpmen_i;
//--------------- Receive Ports - RX Polarity Control Ports ----------------
wire gt1_rxpolarity_i;
//----------------- Receive Ports - RX8B/10B Decoder Ports -----------------
wire [3:0] gt1_rxchariscomma_i;
wire [3:0] gt1_rxcharisk_i;
//------------ Receive Ports -RX Initialization and Reset Ports ------------
wire gt1_rxresetdone_i;
//---------------------- TX Configurable Driver Ports ----------------------
wire [4:0] gt1_txpostcursor_i;
wire [4:0] gt1_txprecursor_i;
//------------------- TX Initialization and Reset Ports --------------------
wire gt1_gttxreset_i;
wire gt1_txuserrdy_i;
//-------------- Transmit Ports - 8b10b Encoder Control Ports --------------
wire [3:0] gt1_txchardispmode_i;
wire [3:0] gt1_txchardispval_i;
//---------------- Transmit Ports - Pattern Generator Ports ----------------
wire gt1_txprbsforceerr_i;
//-------------------- Transmit Ports - TX Buffer Ports --------------------
wire [1:0] gt1_txbufstatus_i;
//------------- Transmit Ports - TX Configurable Driver Ports --------------
wire [3:0] gt1_txdiffctrl_i;
wire [6:0] gt1_txmaincursor_i;
//---------------- Transmit Ports - TX Data Path interface -----------------
wire [31:0] gt1_txdata_i;
//-------------- Transmit Ports - TX Driver and OOB signaling --------------
wire gt1_gtxtxn_i;
wire gt1_gtxtxp_i;
//--------- Transmit Ports - TX Fabric Clock Output Control Ports ----------
wire gt1_txoutclk_i;
wire gt1_txoutclkfabric_i;
wire gt1_txoutclkpcs_i;
//------------------- Transmit Ports - TX Gearbox Ports --------------------
wire [3:0] gt1_txcharisk_i;
//----------- Transmit Ports - TX Initialization and Reset Ports -----------
wire gt1_txpcsreset_i;
wire gt1_txpmareset_i;
wire gt1_txresetdone_i;
//--------------- Transmit Ports - TX Polarity Control Ports ---------------
wire gt1_txpolarity_i;
//---------------- Transmit Ports - pattern Generator Ports ----------------
wire [2:0] gt1_txprbssel_i;
//____________________________COMMON PORTS________________________________
//-------------------- Common Block - Ref Clock Ports ---------------------
wire gt0_gtrefclk1_common_i;
//----------------------- Common Block - QPLL Ports ------------------------
wire gt0_qplllock_i;
wire gt0_qpllrefclklost_i;
wire gt0_qpllreset_i;
//----------------------------- Global Signals -----------------------------
wire drpclk_in_i;
wire DRPCLK_IN;
wire gt0_tx_system_reset_c;
wire gt0_rx_system_reset_c;
wire gt1_tx_system_reset_c;
wire gt1_rx_system_reset_c;
wire tied_to_ground_i;
wire [63:0] tied_to_ground_vec_i;
wire tied_to_vcc_i;
wire [7:0] tied_to_vcc_vec_i;
wire GTTXRESET_IN;
wire GTRXRESET_IN;
wire QPLLRESET_IN;
//--------------------------- User Clocks ---------------------------------
wire gt0_txusrclk_i;
wire gt0_txusrclk2_i;
wire gt0_rxusrclk_i;
wire gt0_rxusrclk2_i;
wire gt1_txusrclk_i;
wire gt1_txusrclk2_i;
wire gt1_rxusrclk_i;
wire gt1_rxusrclk2_i;
wire gt0_txmmcm_lock_i;
wire gt0_txmmcm_reset_i;
wire gt0_rxmmcm_lock_i;
wire gt0_rxmmcm_reset_i;
wire gt1_txmmcm_lock_i;
wire gt1_txmmcm_reset_i;
wire gt1_rxmmcm_lock_i;
wire gt1_rxmmcm_reset_i;
//--------------------------- Reference Clocks ----------------------------
wire q3_clk1_refclk_i;
//--------------------- Frame check/gen Module Signals --------------------
wire gt0_matchn_i;
wire [3:0] gt0_txcharisk_float_i;
wire [15:0] gt0_txdata_float16_i;
wire [31:0] gt0_txdata_float_i;
wire gt0_block_sync_i;
wire gt0_track_data_i;
wire [7:0] gt0_error_count_i;
wire gt0_frame_check_reset_i;
wire gt0_inc_in_i;
wire gt0_inc_out_i;
wire [31:0] gt0_unscrambled_data_i;
wire gt1_matchn_i;
wire [3:0] gt1_txcharisk_float_i;
wire [15:0] gt1_txdata_float16_i;
wire [31:0] gt1_txdata_float_i;
wire gt1_block_sync_i;
wire gt1_track_data_i;
wire [7:0] gt1_error_count_i;
wire gt1_frame_check_reset_i;
wire gt1_inc_in_i;
wire gt1_inc_out_i;
wire [31:0] gt1_unscrambled_data_i;
wire reset_on_data_error_i;
wire track_data_out_i;
//--------------------- Chipscope Signals ---------------------------------
(*mark_debug = "TRUE" *)wire rxresetdone_vio_i;
wire [35:0] tx_data_vio_control_i;
wire [35:0] rx_data_vio_control_i;
wire [35:0] shared_vio_control_i;
wire [35:0] ila_control_i;
wire [35:0] channel_drp_vio_control_i;
wire [35:0] common_drp_vio_control_i;
wire [31:0] tx_data_vio_async_in_i;
wire [31:0] tx_data_vio_sync_in_i;
wire [31:0] tx_data_vio_async_out_i;
wire [31:0] tx_data_vio_sync_out_i;
wire [31:0] rx_data_vio_async_in_i;
wire [31:0] rx_data_vio_sync_in_i;
wire [31:0] rx_data_vio_async_out_i;
wire [31:0] rx_data_vio_sync_out_i;
wire [31:0] shared_vio_in_i;
wire [31:0] shared_vio_out_i;
wire [163:0] ila_in_i;
wire [31:0] channel_drp_vio_async_in_i;
wire [31:0] channel_drp_vio_sync_in_i;
wire [31:0] channel_drp_vio_async_out_i;
wire [31:0] channel_drp_vio_sync_out_i;
wire [31:0] common_drp_vio_async_in_i;
wire [31:0] common_drp_vio_sync_in_i;
wire [31:0] common_drp_vio_async_out_i;
wire [31:0] common_drp_vio_sync_out_i;
wire [31:0] gt0_tx_data_vio_async_in_i;
wire [31:0] gt0_tx_data_vio_sync_in_i;
wire [31:0] gt0_tx_data_vio_async_out_i;
wire [31:0] gt0_tx_data_vio_sync_out_i;
wire [31:0] gt0_rx_data_vio_async_in_i;
wire [31:0] gt0_rx_data_vio_sync_in_i;
wire [31:0] gt0_rx_data_vio_async_out_i;
wire [31:0] gt0_rx_data_vio_sync_out_i;
wire [163:0] gt0_ila_in_i;
wire [31:0] gt0_channel_drp_vio_async_in_i;
wire [31:0] gt0_channel_drp_vio_sync_in_i;
wire [31:0] gt0_channel_drp_vio_async_out_i;
wire [31:0] gt0_channel_drp_vio_sync_out_i;
wire [31:0] gt0_common_drp_vio_async_in_i;
wire [31:0] gt0_common_drp_vio_sync_in_i;
wire [31:0] gt0_common_drp_vio_async_out_i;
wire [31:0] gt0_common_drp_vio_sync_out_i;
wire [31:0] gt1_tx_data_vio_async_in_i;
wire [31:0] gt1_tx_data_vio_sync_in_i;
wire [31:0] gt1_tx_data_vio_async_out_i;
wire [31:0] gt1_tx_data_vio_sync_out_i;
wire [31:0] gt1_rx_data_vio_async_in_i;
wire [31:0] gt1_rx_data_vio_sync_in_i;
wire [31:0] gt1_rx_data_vio_async_out_i;
wire [31:0] gt1_rx_data_vio_sync_out_i;
wire [163:0] gt1_ila_in_i;
wire [31:0] gt1_channel_drp_vio_async_in_i;
wire [31:0] gt1_channel_drp_vio_sync_in_i;
wire [31:0] gt1_channel_drp_vio_async_out_i;
wire [31:0] gt1_channel_drp_vio_sync_out_i;
wire [31:0] gt1_common_drp_vio_async_in_i;
wire [31:0] gt1_common_drp_vio_sync_in_i;
wire [31:0] gt1_common_drp_vio_async_out_i;
wire [31:0] gt1_common_drp_vio_sync_out_i;
wire gttxreset_i;
wire gtrxreset_i;
wire mux_sel_i;
wire user_tx_reset_i;
wire user_rx_reset_i;
wire tx_vio_clk_i;
wire tx_vio_clk_mux_out_i;
wire rx_vio_ila_clk_i;
wire rx_vio_ila_clk_mux_out_i;
wire qpllreset_i;
wire [(80 -32) -1:0] zero_vector_rx_80 ;
wire [(8 -4) -1:0] zero_vector_rx_8 ;
wire [79:0] gt0_rxdata_ila ;
wire [1:0] gt0_rxdatavalid_ila;
wire [7:0] gt0_rxcharisk_ila ;
wire gt0_txmmcm_lock_ila ;
wire gt0_rxmmcm_lock_ila ;
wire gt0_rxresetdone_ila ;
wire gt0_txresetdone_ila ;
wire [79:0] gt1_rxdata_ila ;
wire [1:0] gt1_rxdatavalid_ila;
wire [7:0] gt1_rxcharisk_ila ;
wire gt1_txmmcm_lock_ila ;
wire gt1_rxmmcm_lock_ila ;
wire gt1_rxresetdone_ila ;
wire gt1_txresetdone_ila ;
//**************************** Main Body of Code *******************************
// Static signal Assigments
assign tied_to_ground_i = 1'b0;
assign tied_to_ground_vec_i = 64'h0000000000000000;
assign tied_to_vcc_i = 1'b1;
assign tied_to_vcc_vec_i = 8'hff;
assign zero_vector_rx_80 = 0;
assign zero_vector_rx_8 = 0;
assign q3_clk1_refclk_i = 1'b0;
//***********************************************************************//
// //
//--------------------------- The GT Wrapper ----------------------------//
// //
//***********************************************************************//
// Use the instantiation template in the example directory to add the GT wrapper to your design.
// In this example, the wrapper is wired up for basic operation with a frame generator and frame
// checker. The GTs will reset, then attempt to align and transmit data. If channel bonding is
// enabled, bonding should occur after alignment.
// While connecting the GT TX/RX Reset ports below, please add a delay of
// minimum 500ns as mentioned in AR 43482.
//通道0
assign tx0_clk = gt0_txusrclk2_i ;//用户发送时钟
assign rx0_clk = gt0_rxusrclk2_i ;//用户接收时钟
assign gt0_txdata_i = tx0_data ;//用户发送数据
assign gt0_txcharisk_i = tx0_kchar ;//用户发送K码
assign rx0_data = gt0_rxdata_i ;//用户接收数据
assign rx0_kchar = gt0_rxcharisk_i ;//用户接收K码
assign gt0_tx_system_rstn = gt0_txfsmresetdone_i ;//gtx初始化完成标志
assign gt0_rx_system_rstn = gt0_rxfsmresetdone_i ;//gtx初始化完成标志
//通道1
assign tx1_clk = gt1_txusrclk2_i ;
assign rx1_clk = gt1_rxusrclk2_i ;
assign gt1_txdata_i = tx1_data ;
assign gt1_txcharisk_i = tx1_kchar ;
assign rx1_data = gt1_rxdata_i ;
assign rx1_kchar = gt1_rxcharisk_i ;
assign gt1_tx_system_rstn = gt1_txfsmresetdone_i ;//gtx初始化完成标志
assign gt1_rx_system_rstn = gt1_rxfsmresetdone_i ;//gtx初始化完成标志
gtwizard_0_support #
(
.EXAMPLE_SIM_GTRESET_SPEEDUP ("FALSE"),
.STABLE_CLOCK_PERIOD (10)
)
gtwizard_0_support_i
(
.soft_reset_tx_in (soft_reset_i),
.soft_reset_rx_in (soft_reset_i),
.dont_reset_on_data_error_in (tied_to_ground_i),
.q3_clk1_gtrefclk_pad_n_in (GTREFCLK_PAD_N_IN),
.q3_clk1_gtrefclk_pad_p_in (GTREFCLK_PAD_P_IN),
.gt0_tx_mmcm_lock_out (gt0_txmmcm_lock_i),
.gt0_rx_mmcm_lock_out (gt0_rxmmcm_lock_i),
.gt0_tx_fsm_reset_done_out (gt0_txfsmresetdone_i),
.gt0_rx_fsm_reset_done_out (gt0_rxfsmresetdone_i),
.gt0_data_valid_in (1'b1),
.gt1_tx_mmcm_lock_out (gt1_txmmcm_lock_i),
.gt1_rx_mmcm_lock_out (gt1_rxmmcm_lock_i),
.gt1_tx_fsm_reset_done_out (gt1_txfsmresetdone_i),
.gt1_rx_fsm_reset_done_out (gt1_rxfsmresetdone_i),
.gt1_data_valid_in (1'b1),
.gt0_txusrclk_out(gt0_txusrclk_i),
.gt0_txusrclk2_out(gt0_txusrclk2_i),
.gt0_rxusrclk_out(gt0_rxusrclk_i),
.gt0_rxusrclk2_out(gt0_rxusrclk2_i),
.gt1_txusrclk_out(gt1_txusrclk_i),
.gt1_txusrclk2_out(gt1_txusrclk2_i),
.gt1_rxusrclk_out(gt1_rxusrclk_i),
.gt1_rxusrclk2_out(gt1_rxusrclk2_i),
//_____________________________________________________________________
//_____________________________________________________________________
//GT0 (X1Y12)
//-------------------------- Channel - DRP Ports --------------------------
.gt0_drpaddr_in (gt0_drpaddr_i),
.gt0_drpdi_in (gt0_drpdi_i),
.gt0_drpdo_out (gt0_drpdo_i),
.gt0_drpen_in (gt0_drpen_i),
.gt0_drprdy_out (gt0_drprdy_i),
.gt0_drpwe_in (gt0_drpwe_i),
//------------------------- Digital Monitor Ports --------------------------
.gt0_dmonitorout_out (gt0_dmonitorout_i),
//----------------------------- Loopback Ports -----------------------------
.gt0_loopback_in (gt0_loopback_i),
//---------------------------- Power-Down Ports ----------------------------
.gt0_rxpd_in (gt0_rxpd_i),
.gt0_txpd_in (gt0_txpd_i),
//------------------- RX Initialization and Reset Ports --------------------
.gt0_eyescanreset_in (tied_to_ground_i),
.gt0_rxuserrdy_in (tied_to_vcc_i),
//------------------------ RX Margin Analysis Ports ------------------------
.gt0_eyescandataerror_out (gt0_eyescandataerror_i),
.gt0_eyescantrigger_in (tied_to_ground_i),
//----------------------- Receive Ports - CDR Ports ------------------------
.gt0_rxcdrhold_in (gt0_rxcdrhold_i),
.gt0_rxcdrovrden_in (tied_to_ground_i),
//----------------- Receive Ports - Clock Correction Ports -----------------
.gt0_rxclkcorcnt_out (gt0_rxclkcorcnt_i),
//---------------- Receive Ports - FPGA RX interface Ports -----------------
.gt0_rxdata_out (gt0_rxdata_i),
//----------------- Receive Ports - Pattern Checker Ports ------------------
.gt0_rxprbserr_out (gt0_rxprbserr_i),
.gt0_rxprbssel_in (gt0_rxprbssel_i),
//----------------- Receive Ports - Pattern Checker ports ------------------
.gt0_rxprbscntreset_in (gt0_rxprbscntreset_i),
//---------------- Receive Ports - RX 8B/10B Decoder Ports -----------------
.gt0_rxdisperr_out (gt0_rxdisperr_i),
.gt0_rxnotintable_out (gt0_rxnotintable_i),
//------------------------- Receive Ports - RX AFE -------------------------
.gt0_gtxrxp_in (RXP_IN[0]),
//---------------------- Receive Ports - RX AFE Ports ----------------------
.gt0_gtxrxn_in (RXN_IN[0]),
//----------------- Receive Ports - RX Buffer Bypass Ports -----------------
.gt0_rxbufreset_in (gt0_rxbufreset_i),
.gt0_rxbufstatus_out (gt0_rxbufstatus_i),
//------------ Receive Ports - RX Byte and Word Alignment Ports ------------
.gt0_rxbyteisaligned_out (gt0_rxbyteisaligned_i),
.gt0_rxbyterealign_out (gt0_rxbyterealign_i),
.gt0_rxcommadet_out (gt0_rxcommadet_i),
.gt0_rxmcommaalignen_in (gt0_rxmcommaalignen_i),
.gt0_rxpcommaalignen_in (gt0_rxpcommaalignen_i),
//------------------- Receive Ports - RX Equalizer Ports -------------------
.gt0_rxdfelpmreset_in (tied_to_ground_i),
.gt0_rxmonitorout_out (gt0_rxmonitorout_i),
.gt0_rxmonitorsel_in (2'b00),
//------------- Receive Ports - RX Fabric Output Control Ports -------------
.gt0_rxoutclkfabric_out (gt0_rxoutclkfabric_i),
//----------- Receive Ports - RX Initialization and Reset Ports ------------
.gt0_gtrxreset_in (tied_to_ground_i),
.gt0_rxpcsreset_in (tied_to_ground_i),
.gt0_rxpmareset_in (gt0_rxpmareset_i),
//---------------- Receive Ports - RX Margin Analysis ports ----------------
.gt0_rxlpmen_in (gt0_rxlpmen_i),
//--------------- Receive Ports - RX Polarity Control Ports ----------------
.gt0_rxpolarity_in (gt0_rxpolarity_i),
//----------------- Receive Ports - RX8B/10B Decoder Ports -----------------
.gt0_rxchariscomma_out (gt0_rxchariscomma_i),
.gt0_rxcharisk_out (gt0_rxcharisk_i),
//------------ Receive Ports -RX Initialization and Reset Ports ------------
.gt0_rxresetdone_out (gt0_rxresetdone_i),
//---------------------- TX Configurable Driver Ports ----------------------
.gt0_txpostcursor_in (gt0_txpostcursor_i),
.gt0_txprecursor_in (gt0_txprecursor_i),
//------------------- TX Initialization and Reset Ports --------------------
.gt0_gttxreset_in (tied_to_ground_i),
.gt0_txuserrdy_in (tied_to_vcc_i),
//-------------- Transmit Ports - 8b10b Encoder Control Ports --------------
.gt0_txchardispmode_in (gt0_txchardispmode_i),
.gt0_txchardispval_in (gt0_txchardispval_i),
//---------------- Transmit Ports - Pattern Generator Ports ----------------
.gt0_txprbsforceerr_in (gt0_txprbsforceerr_i),
//-------------------- Transmit Ports - TX Buffer Ports --------------------
.gt0_txbufstatus_out (gt0_txbufstatus_i),
//------------- Transmit Ports - TX Configurable Driver Ports --------------
.gt0_txdiffctrl_in (gt0_txdiffctrl_i),
.gt0_txmaincursor_in (7'b0000000),
//---------------- Transmit Ports - TX Data Path interface -----------------
.gt0_txdata_in (gt0_txdata_i),
//-------------- Transmit Ports - TX Driver and OOB signaling --------------
.gt0_gtxtxn_out (TXN_OUT[0]),
.gt0_gtxtxp_out (TXP_OUT[0]),
//--------- Transmit Ports - TX Fabric Clock Output Control Ports ----------
.gt0_txoutclkfabric_out (gt0_txoutclkfabric_i),
.gt0_txoutclkpcs_out (gt0_txoutclkpcs_i),
//------------------- Transmit Ports - TX Gearbox Ports --------------------
.gt0_txcharisk_in (gt0_txcharisk_i),
//----------- Transmit Ports - TX Initialization and Reset Ports -----------
.gt0_txpcsreset_in (tied_to_ground_i),
.gt0_txpmareset_in (tied_to_ground_i),
.gt0_txresetdone_out (gt0_txresetdone_i),
//--------------- Transmit Ports - TX Polarity Control Ports ---------------
.gt0_txpolarity_in (gt0_txpolarity_i),
//---------------- Transmit Ports - pattern Generator Ports ----------------
.gt0_txprbssel_in (gt0_txprbssel_i),
//_____________________________________________________________________
//_____________________________________________________________________
//GT1 (X1Y13)
//-------------------------- Channel - DRP Ports --------------------------
.gt1_drpaddr_in (gt1_drpaddr_i),
.gt1_drpdi_in (gt1_drpdi_i),
.gt1_drpdo_out (gt1_drpdo_i),
.gt1_drpen_in (gt1_drpen_i),
.gt1_drprdy_out (gt1_drprdy_i),
.gt1_drpwe_in (gt1_drpwe_i),
//------------------------- Digital Monitor Ports --------------------------
.gt1_dmonitorout_out (gt1_dmonitorout_i),
//----------------------------- Loopback Ports -----------------------------
.gt1_loopback_in (gt1_loopback_i),
//---------------------------- Power-Down Ports ----------------------------
.gt1_rxpd_in (gt1_rxpd_i),
.gt1_txpd_in (gt1_txpd_i),
//------------------- RX Initialization and Reset Ports --------------------
.gt1_eyescanreset_in (tied_to_ground_i),
.gt1_rxuserrdy_in (tied_to_vcc_i),
//------------------------ RX Margin Analysis Ports ------------------------
.gt1_eyescandataerror_out (gt1_eyescandataerror_i),
.gt1_eyescantrigger_in (tied_to_ground_i),
//----------------------- Receive Ports - CDR Ports ------------------------
.gt1_rxcdrhold_in (gt1_rxcdrhold_i),
.gt1_rxcdrovrden_in (tied_to_ground_i),
//----------------- Receive Ports - Clock Correction Ports -----------------
.gt1_rxclkcorcnt_out (gt1_rxclkcorcnt_i),
//---------------- Receive Ports - FPGA RX interface Ports -----------------
.gt1_rxdata_out (gt1_rxdata_i),
//----------------- Receive Ports - Pattern Checker Ports ------------------
.gt1_rxprbserr_out (gt1_rxprbserr_i),
.gt1_rxprbssel_in (gt1_rxprbssel_i),
//----------------- Receive Ports - Pattern Checker ports ------------------
.gt1_rxprbscntreset_in (gt1_rxprbscntreset_i),
//---------------- Receive Ports - RX 8B/10B Decoder Ports -----------------
.gt1_rxdisperr_out (gt1_rxdisperr_i),
.gt1_rxnotintable_out (gt1_rxnotintable_i),
//------------------------- Receive Ports - RX AFE -------------------------
.gt1_gtxrxp_in (RXP_IN[1]),
//---------------------- Receive Ports - RX AFE Ports ----------------------
.gt1_gtxrxn_in (RXN_IN[1]),
//----------------- Receive Ports - RX Buffer Bypass Ports -----------------
.gt1_rxbufreset_in (gt1_rxbufreset_i),
.gt1_rxbufstatus_out (gt1_rxbufstatus_i),
//------------ Receive Ports - RX Byte and Word Alignment Ports ------------
.gt1_rxbyteisaligned_out (gt1_rxbyteisaligned_i),
.gt1_rxbyterealign_out (gt1_rxbyterealign_i),
.gt1_rxcommadet_out (gt1_rxcommadet_i),
.gt1_rxmcommaalignen_in (1'b1),
.gt1_rxpcommaalignen_in (1'b1),
//------------------- Receive Ports - RX Equalizer Ports -------------------
.gt1_rxdfelpmreset_in (tied_to_ground_i),
.gt1_rxmonitorout_out (gt1_rxmonitorout_i),
.gt1_rxmonitorsel_in (2'b00),
//------------- Receive Ports - RX Fabric Output Control Ports -------------
.gt1_rxoutclkfabric_out (gt1_rxoutclkfabric_i),
//----------- Receive Ports - RX Initialization and Reset Ports ------------
.gt1_gtrxreset_in (tied_to_ground_i),
.gt1_rxpcsreset_in (tied_to_ground_i),
.gt1_rxpmareset_in (gt1_rxpmareset_i),
//---------------- Receive Ports - RX Margin Analysis ports ----------------
.gt1_rxlpmen_in (gt1_rxlpmen_i),
//--------------- Receive Ports - RX Polarity Control Ports ----------------
.gt1_rxpolarity_in (gt1_rxpolarity_i),
//----------------- Receive Ports - RX8B/10B Decoder Ports -----------------
.gt1_rxchariscomma_out (gt1_rxchariscomma_i),
.gt1_rxcharisk_out (gt1_rxcharisk_i),
//------------ Receive Ports -RX Initialization and Reset Ports ------------
.gt1_rxresetdone_out (gt1_rxresetdone_i),
//---------------------- TX Configurable Driver Ports ----------------------
.gt1_txpostcursor_in (gt1_txpostcursor_i),
.gt1_txprecursor_in (gt1_txprecursor_i),
//------------------- TX Initialization and Reset Ports --------------------
.gt1_gttxreset_in (tied_to_ground_i),
.gt1_txuserrdy_in (tied_to_vcc_i),
//-------------- Transmit Ports - 8b10b Encoder Control Ports --------------
.gt1_txchardispmode_in (gt1_txchardispmode_i),
.gt1_txchardispval_in (gt1_txchardispval_i),
//---------------- Transmit Ports - Pattern Generator Ports ----------------
.gt1_txprbsforceerr_in (gt1_txprbsforceerr_i),
//-------------------- Transmit Ports - TX Buffer Ports --------------------
.gt1_txbufstatus_out (gt1_txbufstatus_i),
//------------- Transmit Ports - TX Configurable Driver Ports --------------
.gt1_txdiffctrl_in (gt1_txdiffctrl_i),
.gt1_txmaincursor_in (7'b0000000),
//---------------- Transmit Ports - TX Data Path interface -----------------
.gt1_txdata_in (gt1_txdata_i),
//-------------- Transmit Ports - TX Driver and OOB signaling --------------
.gt1_gtxtxn_out (TXN_OUT[1]),
.gt1_gtxtxp_out (TXP_OUT[1]),
//--------- Transmit Ports - TX Fabric Clock Output Control Ports ----------
.gt1_txoutclkfabric_out (gt1_txoutclkfabric_i),
.gt1_txoutclkpcs_out (gt1_txoutclkpcs_i),
//------------------- Transmit Ports - TX Gearbox Ports --------------------
.gt1_txcharisk_in (gt1_txcharisk_i),
//----------- Transmit Ports - TX Initialization and Reset Ports -----------
.gt1_txpcsreset_in (tied_to_ground_i),
.gt1_txpmareset_in (tied_to_ground_i),
.gt1_txresetdone_out (gt1_txresetdone_i),
//--------------- Transmit Ports - TX Polarity Control Ports ---------------
.gt1_txpolarity_in (gt1_txpolarity_i),
//---------------- Transmit Ports - pattern Generator Ports ----------------
.gt1_txprbssel_in (gt1_txprbssel_i),
//____________________________COMMON PORTS________________________________
.gt0_qplllock_out(),
.gt0_qpllrefclklost_out(),
.gt0_qplloutclk_out(),
.gt0_qplloutrefclk_out(),
.sysclk_in(drpclk_in_i)
);
assign drpclk_in_i = drp_clk;
//***********************************************************************//
// //
//--------------------------- User Module Resets-------------------------//
// //
//***********************************************************************//
// All the User Modules i.e. FRAME_GEN, FRAME_CHECK and the sync modules
// are held in reset till the RESETDONE goes high.
// The RESETDONE is registered a couple of times on *USRCLK2 and connected
// to the reset of the modules
always @(posedge gt0_rxusrclk2_i or negedge gt0_rxresetdone_i)
begin
if (!gt0_rxresetdone_i)
begin
gt0_rxresetdone_r <= `DLY 1'b0;
gt0_rxresetdone_r2 <= `DLY 1'b0;
gt0_rxresetdone_r3 <= `DLY 1'b0;
end
else
begin
gt0_rxresetdone_r <= `DLY gt0_rxresetdone_i;
gt0_rxresetdone_r2 <= `DLY gt0_rxresetdone_r;
gt0_rxresetdone_r3 <= `DLY gt0_rxresetdone_r2;
end
end
always @(posedge gt0_txusrclk2_i or negedge gt0_txfsmresetdone_i)
begin
if (!gt0_txfsmresetdone_i)
begin
gt0_txfsmresetdone_r <= `DLY 1'b0;
gt0_txfsmresetdone_r2 <= `DLY 1'b0;
end
else
begin
gt0_txfsmresetdone_r <= `DLY gt0_txfsmresetdone_i;
gt0_txfsmresetdone_r2 <= `DLY gt0_txfsmresetdone_r;
end
end
always @(posedge gt1_rxusrclk2_i or negedge gt1_rxresetdone_i)
begin
if (!gt1_rxresetdone_i)
begin
gt1_rxresetdone_r <= `DLY 1'b0;
gt1_rxresetdone_r2 <= `DLY 1'b0;
gt1_rxresetdone_r3 <= `DLY 1'b0;
end
else
begin
gt1_rxresetdone_r <= `DLY gt1_rxresetdone_i;
gt1_rxresetdone_r2 <= `DLY gt1_rxresetdone_r;
gt1_rxresetdone_r3 <= `DLY gt1_rxresetdone_r2;
end
end
always @(posedge gt1_txusrclk2_i or negedge gt1_txfsmresetdone_i)
begin
if (!gt1_txfsmresetdone_i)
begin
gt1_txfsmresetdone_r <= `DLY 1'b0;
gt1_txfsmresetdone_r2 <= `DLY 1'b0;
end
else
begin
gt1_txfsmresetdone_r <= `DLY gt1_txfsmresetdone_i;
gt1_txfsmresetdone_r2 <= `DLY gt1_txfsmresetdone_r;
end
end
//-------------------------Debug Signals assignment--------------------
assign gt0_rxlpmen_i = tied_to_vcc_i;
assign gt1_rxlpmen_i = tied_to_vcc_i;
//------------ optional Ports assignments --------------
assign gt0_rxprbscntreset_i = tied_to_ground_i;
assign gt0_rxprbssel_i = 0;
assign gt0_loopback_i = 0;
assign gt0_txdiffctrl_i = 0;
assign gt0_rxbufreset_i = tied_to_ground_i;
assign gt0_rxcdrhold_i = tied_to_ground_i;
//------GTH/GTP
assign gt0_rxdfelpmreset_i = tied_to_ground_i;
assign gt0_rxpmareset_i = tied_to_ground_i;
assign gt0_rxpolarity_i = tied_to_ground_i;
assign gt0_rxpd_i = 0;
assign gt0_txprecursor_i = 0;
assign gt0_txpostcursor_i = 0;
assign gt0_txchardispmode_i = 0;
assign gt0_txchardispval_i = 0;
assign gt0_txpolarity_i = tied_to_ground_i;
assign gt0_txpd_i = 0;
assign gt0_txprbsforceerr_i = tied_to_ground_i;
assign gt0_txprbssel_i = 0;
assign gt1_rxprbscntreset_i = tied_to_ground_i;
assign gt1_rxprbssel_i = 0;
assign gt1_loopback_i = 0;
assign gt1_txdiffctrl_i = 0;
assign gt1_rxbufreset_i = tied_to_ground_i;
assign gt1_rxcdrhold_i = tied_to_ground_i;
//------GTH/GTP
assign gt1_rxdfelpmreset_i = tied_to_ground_i;
assign gt1_rxpmareset_i = tied_to_ground_i;
assign gt1_rxpolarity_i = tied_to_ground_i;
assign gt1_rxpd_i = 0;
assign gt1_txprecursor_i = 0;
assign gt1_txpostcursor_i = 0;
assign gt1_txchardispmode_i = 0;
assign gt1_txchardispval_i = 0;
assign gt1_txpolarity_i = tied_to_ground_i;
assign gt1_txpd_i = 0;
assign gt1_txprbsforceerr_i = tied_to_ground_i;
assign gt1_txprbssel_i = 0;
//------------------------------------------------------
// assign resets for frame_gen modules
assign gt0_tx_system_reset_c = !gt0_txfsmresetdone_r2;
assign gt1_tx_system_reset_c = !gt1_txfsmresetdone_r2;
// assign resets for frame_check modules
assign gt0_rx_system_reset_c = !gt0_rxresetdone_r3;
assign gt1_rx_system_reset_c = !gt1_rxresetdone_r3;
assign gt0_drpaddr_i = 9'd0;
assign gt0_drpdi_i = 16'd0;
assign gt0_drpen_i = 1'b0;
assign gt0_drpwe_i = 1'b0;
assign gt1_drpaddr_i = 9'd0;
assign gt1_drpdi_i = 16'd0;
assign gt1_drpen_i = 1'b0;
assign gt1_drpwe_i = 1'b0;
assign soft_reset_i = tied_to_ground_i;
endmodule
工程结构如下图所示:
整个工程可以分成三个部分:HDMI驱动模块、数据传输模块和数据缓存模块,其中HDMI驱动模块与数据缓存模块在前面都验证过,今天着重讲解一下数据传输模块。video_encode模块对视频流进行编码,外部HDMI进来的视频流是16位的,首先使用异步FIFO进行缓冲,16位进32位出,以视频vsync信号上升沿时刻算起,当vsync上升沿到来时,将上升沿编码为: 32'h55_00_00_bc ,32'h55_00_01_bc,当FIFO中的数据量达不到要求时,发送无效数据:32'h55_00_02_bc, 32'h55_00_03_bc交替发送,当FIFO中有一定量的数据后,首先发送1个32位的32'h55_00_04_bc表明一行就要开始传 输,然后发送每行数据行号+bc,紧接着将FIFO中的数据依次发出去,发送完一行数据后,发送32'h55_00_05_bc,表 明一行数据发送完成,紧接着发送上述的无效数据:32'h55_00_02_bc,32'h55_00_03_bc交替发送,等待vsync下降 沿到来,将其编码为32'h55_00_06_bc,32'h55_00_07_bc发出,到此一行发送结束,以同样的编码将视频流每一行的数据发送给gtx即可。整个编码过程的实现也是比较简单的,但是本次代码中的状态机可能和之前遇到的三段式状态机有一定的区别,具体实现代码如下:
`timescale 1ns / 1ps
module video_encode #(
parameter VID_H = 1920 , //待编码数据水平分辨率
parameter VID_V = 1080 , //待编码数据垂直分辨率
parameter VID_DW = 16 , //输入待编码数据位宽
parameter CODED_DW = 32 , //编码后的数据位宽
parameter FIFO_VTH = 960 //FIFO深度
)
(
input rst_n , //复位信号
input vid_clk , //待编码数据输入时钟
input coded_clk , //编码时钟
input vid_vs , //待编码数据场同步信号
input vid_de , //待编码数据有效信号
input [VID_DW-1 :0] vid_data , //待编码数据
output reg [CODED_DW-1:0] coded_data , //编码后的数据
output reg [3:0] coded_ctr //数据对齐控制信号
);
localparam CODE_H = VID_H/2 ; //编码数据水平分辨率,因为位宽关系为一半
localparam FIFO_VTH_SET = FIFO_VTH/2 ; //
localparam frame_sys0 = 0 , //上升沿检测状态
frame_sys1 = 1 , //检测到上升沿后延迟一拍
h_data_begin = 2 , //开始发送一行数据同步
h_data_index = 3 , //发送每行数据+bc
h_data = 4 , //发送数据状态
h_data_end = 5 , //发送结束状态
unuse_data0 = 6 , //发送无用数据
unuse_data1 = 7 , //发送无用数据
frame_end0 = 8 , //发送一帧数据结束信号1
frame_end1 = 9 ; //发送一帧数据结束信号2
wire vs_pose ; //场同步信号上升沿
wire vs_nege ; //场同步信号下降沿
wire [CODED_DW-1:0]dout ; //FIFO中读出的数据
wire full ; //FIFO满信号
wire empty ; //FIFO空信号
wire [10 : 0] coded_data_count ; //编码数据计数
wire [11 : 0] vid_data_count ; //输入带编码数据计数
//(*mark_debug = "TRUE" *)
reg [31:0] hcnt ; //行计数
reg [31:0] vcnt ; //场计数
reg [3:0] state ; //状态
reg [3:0] vid_vs_r ; //场同步信号打拍,便于检测上升沿
reg rd_en ; //FIFO读使能
reg [7:0] fifo_rst_cnt ; //FIFO复位计数
//场同步信号打拍
always@(posedge coded_clk)
if(!rst_n)
vid_vs_r <= 'd0;
else
vid_vs_r <= {vid_vs_r[2:0],vid_vs};
//上升沿与下降沿检测
assign vs_pose = ~vid_vs_r[3]&&vid_vs_r[2];
assign vs_nege = vid_vs_r[3]&&~vid_vs_r[2];
//场计数
always@(posedge coded_clk )
if(!rst_n || vs_pose)
vcnt <= 'd0;
else if(vcnt == VID_V)//计满一帧
vcnt <= 'd0;
else if(coded_data == 32'h55_00_04_bc)//每发送一行数据
vcnt <= vcnt + 1'b1;
else
vcnt <= vcnt;
//行计数
always@(posedge coded_clk)
if(!rst_n || vs_pose)
hcnt <= 'd0;
else if(hcnt == (CODE_H - 11'b1))//一行数据编码完成
hcnt <= 'd0;
else if(rd_en==1'b1)//每对两个像素进行编码
hcnt <= hcnt + 1'b1;
else
hcnt <= hcnt;
//状态机
always@(posedge coded_clk)begin
if(!rst_n) begin
rd_en <= 1'b0;
state <= unuse_data0;
coded_data <= 32'd0;
coded_ctr <= 4'd0;
end
else if(vs_pose==1'b1) begin
state <= frame_sys0;
rd_en <= 1'b0;
end
else if(vs_nege==1'b1) begin
state <= frame_end0;
rd_en <= 1'b0;
end
else begin
case(state)
frame_sys0:begin //发送帧同步信号55_00_00_bc
state <= frame_sys1;
coded_data <= 32'h55_00_00_bc;
coded_ctr <= 4'b0001;
end
frame_sys1:begin //发送帧同步信号55_00_01_bc
state <= unuse_data0;
coded_data <= 32'h55_00_01_bc;
coded_ctr <= 4'b0001;
end
unuse_data0: //发送无用的信号55_00_02_bc
begin
state <= unuse_data1;
coded_data <= 32'h55_00_02_bc;
coded_ctr <= 4'b0001;
end
unuse_data1: //发送无用的信号55_00_03_bc
begin
if(coded_data_count >= FIFO_VTH_SET) //当FIFO 中有一行数据
begin
state <= h_data_begin;
end
else
begin
state <= unuse_data0;
coded_data <= 32'h55_00_03_bc;
end
end
h_data_begin: //发送一行数据开始同步信号
begin
state <= h_data_index;
coded_data <= 32'h55_00_04_bc;
coded_ctr <= 4'b0001;
end
h_data_index: //发送每行数据行号+bc
begin
state <= h_data;
coded_data <= {vcnt[23:0],8'hbc};
coded_ctr <= 4'b0001;
end
h_data: //开始发送FIFO中的一行视频图像数据
begin
if(hcnt < CODE_H - 1'b1) begin
state <= h_data;
coded_data <= dout;
coded_ctr <= 4'b0000;
rd_en <= 1'b1;
end
else begin
state <= h_data_end;
coded_data <= dout;
rd_en <= 1'b0;
end
end
h_data_end: //发送一行数据已接收信号
begin
state <= unuse_data0;
coded_data <= 32'h55_00_05_bc;
coded_ctr <= 4'b0001;
end
frame_end0: //发送帧结束信号55_00_06_bc
begin
state <= frame_end1;
coded_data <= 32'h55_00_06_bc;
coded_ctr <= 4'b0001;
end
frame_end1: //发送帧结束信号55_00_07_bc
begin
state <= unuse_data0;
coded_data <= 32'h55_00_07_bc;
coded_ctr <= 4'b0001;
end
default:;
endcase
end
end
//FIFO复位计数
always@(posedge coded_clk)
if(vs_pose == 1'b1 )begin
fifo_rst_cnt <= 8'd50;
end
else begin
if(fifo_rst_cnt > 8'd0)
fifo_rst_cnt<=fifo_rst_cnt-1'b1;
end
wire fifo_rst = (fifo_rst_cnt>=8'd10)&&(fifo_rst_cnt<8'd50)||(!rst_n);//高电平复位
tx_fifo u1_tx_fifo (
.rst(fifo_rst),
.wr_clk (vid_clk ),
.rd_clk (coded_clk ),
.din (vid_data ),
.wr_en (vid_de ),
.rd_en (rd_en ),
.dout (dout ),
.full (full ),
.empty (empty ),
.rd_data_count (coded_data_count),
.wr_data_count (vid_data_count )
);
ila_3 your_instance_name_0 (
.clk(coded_clk), // input wire clk
.probe0(vid_de), // input wire [0:0] probe0
.probe1(rd_en), // input wire [0:0] probe1
.probe2(vid_data), // input wire [15:0] probe2
.probe3(coded_data), // input wire [31:0] probe3
.probe4(coded_ctr), // input wire [3:0] probe4
.probe5(vs_pose), // input wire [0:0] probe5
.probe6(state), // input wire [0:0] probe6
.probe7(h_cnt), // input wire [0:0] probe7
.probe8(vid_vs), // input wire [0:0] probe8
.probe9(vid_clk), // input wire [0:0] probe9
.probe10(fifo_rst), // input wire [0:0] probe10
.probe11(coded_data_count), // input wire [10:0] probe11
.probe12(vid_data_count ), // input wire [11:0] probe12
.probe13(vcnt) // input wire [31:0] probe13
);
endmodule
data_align模块则用于数据对齐功能,那如何才能将数据进行对齐呢?这就需要用到k码了,在数据编码模块中我们在每一行开始、结束,每一帧开始或者结束的时候低8位数据均为bc这就是k码,接收端在接收到数据之后先检查k码,而检查到k码错位之后利用代码将其进行对齐,具体代码如下所示:
`timescale 1ns / 1ps
module data_align(
input rst_n , //复位
input rx_clk , //接收时钟
input [31:0] rx_data , //接收数据
input [3:0] rx_ctrl , //接收k码
output reg [31:0] rx_data_align , //对齐数据
output reg [3:0] rx_ctrl_align //对齐k码
);
reg [31:0] rx_data_r ;
reg [3:0] align_bit ;
reg [3:0] rx_ctrl_r ;
always@(posedge rx_clk or negedge rst_n)
if(!rst_n)
align_bit <= 4'd0;
else if(rx_ctrl != 4'd0)
align_bit <= rx_ctrl;
else
align_bit <= align_bit;
always@(posedge rx_clk or negedge rst_n)
if(!rst_n)
rx_data_r <= 'd0;
else
rx_data_r <= rx_data;
always@(posedge rx_clk or negedge rst_n)
if(!rst_n)
rx_ctrl_r <= 4'd0;
else
rx_ctrl_r <= rx_ctrl;
always@(posedge rx_clk or negedge rst_n)
if(!rst_n)
rx_data_align <= 32'd0;
else
case(align_bit)
4'b0001:
rx_data_align <= rx_data;//没错位直接赋值
4'b0100:
rx_data_align <= {rx_data[15:0],rx_data_r[31:16]};//错位进行拼接
default:
rx_data_align <= 32'd0;
endcase
always@(posedge rx_clk or negedge rst_n)
if(!rst_n)
rx_ctrl_align <= 4'd0;
else
case(align_bit)
4'b0001:
rx_ctrl_align <= rx_ctrl;
4'b0100:
rx_ctrl_align <= {rx_ctrl[1:0],rx_ctrl_r[3:2]};//错位进行拼接
default:
rx_ctrl_align <= 4'd0;
endcase
endmodule
video_decode则用于对接收数据进行解码,将对齐的过后的编码数据通过异步FIFO进行缓冲,把32位的编码数据转换成相应的rgb565的图像数据,当检测到帧同步信号(32'h55_00_00_bc、32'h55_00_01_bc)和帧结束信 号(32'h55_00_06_bc,32'h55_00_07_bc),会去恢复出vsync信号上升和下降沿。当检测到行传输信号(32'h55_00_04_bc)之后,将hsync信号拉高至行计数结束。当检测到Vsync上升沿,一旦FIFO中有一行数据之后,会去恢复出数据有效 de信号。,具体实现如下所示:
`timescale 1ns / 1ps
module video_decode #(
parameter VID_H = 1920,
parameter VID_V = 1080,
parameter VID_DW = 16 ,
parameter CODED_DW = 32 ,
parameter FIFO_VTH = 960
)
(
input rst_n , //复位信号
input vid_clk , //数据输出时钟
output reg vid_vs , //输出场同步信号
output reg vid_de , //输出数据有效信号
output [VID_DW-1 :0] vid_data , //输出数据
input coded_clk , //解码时钟
input [CODED_DW-1:0] coded_data , //待解码数据
input [3:0] coded_ctr //接收k码
);
parameter CODE_H = VID_H/2 ; //这里除以二是因为待解码数据与解码后的数据关系为二分之一
localparam IDLE = 0 , //状态机状态
READ_LINE = 1 ;
reg [2:0] state ;
reg [CODED_DW-1:0] coded_data_r ; //暂存待解码数据
reg [3:0] vid_vs_r ;
reg wr_en ; //FIFO写使能
reg wr_en_r ;
reg [31:0] wr_cnt ; //FIFO写计数
reg [7:0] fifo_rst_cnt ; //FIFO复位计数
wire full ;
wire empty ;
wire [11 : 0] rd_data_count ; //读数据计数
wire [10 : 0] wr_data_count ; //写数据计数
reg [31:0] hcnt ; //行计数
always@(posedge coded_clk or negedge rst_n)
if(!rst_n)
coded_data_r <= 'd0;
else
coded_data_r <= coded_data;
always@(posedge coded_clk or negedge rst_n)
if(!rst_n)
vid_vs <= 1'b0;
else if(coded_ctr == 4'b0001 && coded_data == 32'h55_00_01_bc&&coded_data_r==32'h55_00_00_bc)//帧上升沿恢复
vid_vs <= 1'b1;
else if(coded_ctr == 4'b0001 && coded_data == 32'h55_00_07_bc&&coded_data_r == 32'h55_00_06_bc)//帧下降沿恢复
vid_vs <= 1'b0;
else
vid_vs <= vid_vs;
always@(posedge coded_clk or negedge rst_n)
if(!rst_n || vid_vs)
wr_en <= 1'b0;
else if((wr_cnt == CODE_H - 1'b1 ))
wr_en <= 1'b0;
else if(coded_ctr == 4'b0001 && coded_data == 32'h55_00_04_bc)//检测到一行数据
wr_en <= 1'b1;
else
wr_en <= wr_en;
always@(posedge coded_clk or negedge rst_n)//打一拍
if(!rst_n)
wr_en_r <= 'd0;
else
wr_en_r <= wr_en;
always@(posedge coded_clk or negedge rst_n)//wr_en_r拉高一行的长度,把32位带解码数据写入FIFO
if(!rst_n || vid_vs)
wr_cnt <= 'd0;
else if((wr_cnt == CODE_H -1'b1))
wr_cnt <= 'd0;
else if(wr_en == 1'b1)
wr_cnt <= wr_cnt + 1'b1;
else
wr_cnt <= wr_cnt;
always@(posedge vid_clk )
vid_vs_r <= {vid_vs_r[2:0],vid_vs};
always@(posedge vid_clk )
if(!rst_n || vid_vs_r[3])
hcnt <= 'd0;
else if(hcnt == VID_H - 1'b1)
hcnt <= 'd0;
else if(vid_de == 1'b1)
hcnt <= hcnt + 1'b1;
always@(posedge vid_clk)//从FIFO中读取16位解码数据
if(!rst_n || vid_vs_r[3]) begin
state <= IDLE;
vid_de <= 1'b0;
end
else begin
case(state)
IDLE:
if(rd_data_count >= FIFO_VTH) begin //FIFO数据大于一行
state <= READ_LINE;
end
READ_LINE:
if(hcnt < VID_H - 1'b1) begin
vid_de <= 1'b1;
end
else begin
state <= IDLE;
vid_de <= 1'b0;
end
default:state <= IDLE ;
endcase
end
always@(posedge coded_clk)
if(vid_vs == 1'b1 )begin
fifo_rst_cnt <= 8'd50;
end
else begin
if(fifo_rst_cnt >8'd0)
fifo_rst_cnt<=fifo_rst_cnt-1'b1;
end
wire fifo_rst = (fifo_rst_cnt>=8'd10)&&(fifo_rst_cnt<8'd50)||(!rst_n);
rx_fifo u1_rx_fifo (
.rst (fifo_rst ),
.wr_clk (coded_clk ),
.rd_clk (vid_clk ),
.din (coded_data ),
.wr_en (wr_en_r ),
.rd_en (vid_de ),
.dout (vid_data ),
.full (full ),
.empty (empty ),
.rd_data_count (rd_data_count ),
.wr_data_count (wr_data_count )
);
ila_4 your_instance_name (
.clk(coded_clk), // input wire clk
.probe0(wr_en_r), // input wire [0:0] probe0
.probe1(vid_vs), // input wire [0:0] probe1
.probe2(vid_de), // input wire [0:0] probe2
.probe3(vid_data), // input wire [15:0] probe3
.probe4(code_data), // input wire [31:0] probe4
.probe5(coded_ctr), // input wire [3:0] probe5
.probe6(state), // input wire [1:0] probe6
.probe7(hcnt) // input wire [0:0] probe7
);
endmodule
顶层模块如下所示:
module uiAurora_8b10b_vid #(
parameter VID_H = 1920 , //水平分辨率
parameter VID_V = 1080 , //垂直分辨率
parameter FIFO_VTH = 960 //FIFO深度
)
(
input clk_100M , //系统时钟
input vid_in_clk , //数据输入时钟,此处为adv7611输入时钟,148.5M
input vid_in_vs , //输入场同步信号
input vid_in_de , //输入有效信号
input [15:0] vid_in_data , //输入数据
input vid_out_clk , //数据输出时钟,此处为148.5M
output vid_out_vs , //输出场同步信号
output vid_out_de , //输出有效信号
output [15:0] vid_out_data , //输出数据
input GT_REF_P , //GTX参考时钟差分信号
input GT_REF_N ,
input [1:0] rxn , //GTX接收数据差分信号
input [1:0] rxp ,
output [1:0] txn , //GTX发送数据差分信号
output [1:0] txp
);
//gt
wire tx_clk ; //发送时钟
wire [31:0] tx_data ; //发送数据
wire [3:0] tx_kchar ; //发送k码
wire rx_clk ; //接收时钟
wire [31:0] rx_data ; //接收数据
wire [3:0] rx_kchar ; //接收k码
//通道0
wire tx0_clk ;
wire [31:0] tx0_data ;
wire [3:0] tx0_kchar ;
wire rx0_clk ;
wire [31:0] rx0_data ;
wire [3:0] rx0_kchar ;
//通道1
wire tx1_clk ;
wire [31:0] tx1_data ;
wire [3:0] tx1_kchar ;
wire rx1_clk ;
wire [31:0] rx1_data ;
wire [3:0] rx1_kchar ;
wire [31:0] rx_data_align ; //对齐后的数据
wire [3:0] rx_ctrl_align ; //对齐后的k码
wire gt0_tx_rstn ; //通道0发送复位
wire gt0_rx_rstn ; //通道0接收复位
wire gt1_tx_rstn ; //通道1发送复位
wire gt1_rx_rstn ; //通道1接收复位
assign tx_clk = tx0_clk ;
assign tx0_data = tx_data ;
assign tx0_kchar = tx_kchar ;
assign rx_clk = rx1_clk ;
assign rx_data = rx1_data ;
assign rx_kchar = rx1_kchar ;
//对视频流进行编码
video_encode#(
.VID_H (VID_H ),
.VID_V (VID_V ),
.VID_DW (16 ),
.CODED_DW (32 ),
.FIFO_VTH (FIFO_VTH )
)
u1_video_encode(
.rst_n (gt0_tx_rstn ),
.vid_clk (vid_in_clk ),
.vid_vs (vid_in_vs ),
.vid_de (vid_in_de ),
.vid_data (vid_in_data ),
.coded_clk (tx_clk ),
.coded_data (tx_data ),
.coded_ctr (tx_kchar )
);
//对视频流进行解码
video_decode#(
.VID_H (VID_H ),
.VID_V (VID_V ),
.VID_DW (16 ),
.CODED_DW (32 ),
.FIFO_VTH (FIFO_VTH )
)
u1_video_decode(
.rst_n (gt1_rx_rstn ),
.vid_clk (vid_out_clk ),
.vid_vs (vid_out_vs ),
.vid_de (vid_out_de ),
.vid_data (vid_out_data ),
.coded_clk (rx_clk ),
.coded_data (rx_data_align ),
.coded_ctr (rx_ctrl_align )
);
//如果数据错位进行纠正对齐
data_align u1_data_align(
.rst_n (gt1_rx_rstn ),
.rx_clk (rx_clk ),
.rx_data (rx_data ),
.rx_ctrl (rx_kchar ),
.rx_data_align (rx_data_align ),
.rx_ctrl_align (rx_ctrl_align )
);
//gtx传输视频
gtwizard_0_exdes u1_gtwizard_0_exdes(
.GTREFCLK_PAD_N_IN (GT_REF_N ),
.GTREFCLK_PAD_P_IN (GT_REF_P ),
.drp_clk (clk_100M ),
.tx0_clk (tx0_clk ),
.tx0_data (tx0_data ),
.tx0_kchar (tx0_kchar ),
.rx0_clk (rx0_clk ),
.rx0_data (rx0_data ),
.rx0_kchar (rx0_kchar ),
.gt0_tx_system_rstn (gt0_tx_rstn ),
.gt0_rx_system_rstn (gt0_rx_rstn ),
.tx1_clk (tx1_clk ),
.tx1_data (tx1_data ),
.tx1_kchar (tx1_kchar ),
.rx1_clk (rx1_clk ),
.rx1_data (rx1_data ),
.rx1_kchar (rx1_kchar ),
.gt1_tx_system_rstn (gt1_tx_rstn ),
.gt1_rx_system_rstn (gt1_rx_rstn ),
.RXN_IN (rxn ),
.RXP_IN (rxp ),
.TXN_OUT (txn ),
.TXP_OUT (txp )
);
endmodule
搭建好工程之后利用ila抓取波形如下所示:
可以看到发送端与接收端都没有问题但是DDR3中却没有数据读出,检查之后发现是video timing cntroller产生的时序有问题,改正之后得到的结果如下图所示:
总结:此次的工程虽然比较简单但也折腾了几天才折腾出来,其中一个重要的原因就是在生成官方例程之后没有仔细的对官方例程进行更改,导致了接收端数据不能对齐的情况,甚至出现了k码为1111的情况,因此生成ip后一定要对官方例程进行仔细更改,以免出现错误。