URL
https://opencores.org/ocsvn/pcie_sg_dma/pcie_sg_dma/trunk
Subversion Repositories pcie_sg_dma
[/] [pcie_sg_dma/] [branches/] [Virtex6/] [ML605_ISE13.3/] [ipcore_dir_ISE13.3/] [v6_pcie_v1_7_x4/] [source/] [gtx_rx_valid_filter_v6.v] - Rev 13
Compare with Previous | Blame | View Log
//----------------------------------------------------------------------------- // // (c) Copyright 2009-2011 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. // //----------------------------------------------------------------------------- // Project : Virtex-6 Integrated Block for PCI Express // File : gtx_rx_valid_filter_v6.v // Version : 1.7 `timescale 1ns / 1ns module GTX_RX_VALID_FILTER_V6 #( parameter CLK_COR_MIN_LAT = 28 ) ( output [1:0] USER_RXCHARISK, output [15:0] USER_RXDATA, output USER_RXVALID, output USER_RXELECIDLE, output [ 2:0] USER_RX_STATUS, output USER_RX_PHY_STATUS, input [1:0] GT_RXCHARISK, input [15:0] GT_RXDATA, input GT_RXVALID, input GT_RXELECIDLE, input [ 2:0] GT_RX_STATUS, input GT_RX_PHY_STATUS, input PLM_IN_L0, input PLM_IN_RS, input USER_CLK, input RESET ); parameter TCQ = 1; parameter EIOS_DET_IDL = 5'b00001; parameter EIOS_DET_NO_STR0 = 5'b00010; parameter EIOS_DET_STR0 = 5'b00100; parameter EIOS_DET_STR1 = 5'b01000; parameter EIOS_DET_DONE = 5'b10000; parameter EIOS_COM = 8'hBC; parameter EIOS_IDL = 8'h7C; parameter FTSOS_COM = 8'hBC; parameter FTSOS_FTS = 8'h3C; reg [4:0] reg_state_eios_det; wire [4:0] state_eios_det; reg reg_eios_detected; wire eios_detected; reg reg_symbol_after_eios; wire symbol_after_eios; parameter USER_RXVLD_IDL = 4'b0001; parameter USER_RXVLD_EI = 4'b0010; parameter USER_RXVLD_EI_DB0 = 4'b0100; parameter USER_RXVLD_EI_DB1 = 4'b1000; reg [3:0] reg_state_rxvld_ei; wire [3:0] state_rxvld_ei; reg [4:0] reg_rxvld_count; wire [4:0] rxvld_count; reg [3:0] reg_rxvld_fallback; wire [3:0] rxvld_fallback; reg [1:0] gt_rxcharisk_q; reg [15:0] gt_rxdata_q; reg gt_rxvalid_q; reg gt_rxelecidle_q; reg gt_rxelecidle_qq; reg [ 2:0] gt_rx_status_q; reg gt_rx_phy_status_q; reg gt_rx_is_skp0_q; reg gt_rx_is_skp1_q; // EIOS detector always @(posedge USER_CLK) begin if (RESET) begin reg_eios_detected <= #TCQ 1'b0; reg_state_eios_det <= #TCQ EIOS_DET_IDL; reg_symbol_after_eios <= #TCQ 1'b0; gt_rxcharisk_q <= #TCQ 2'b00; gt_rxdata_q <= #TCQ 16'h0; gt_rxvalid_q <= #TCQ 1'b0; gt_rxelecidle_q <= #TCQ 1'b0; gt_rxelecidle_qq <= #TCQ 1'b0; gt_rx_status_q <= #TCQ 3'b000; gt_rx_phy_status_q <= #TCQ 1'b0; gt_rx_is_skp0_q <= #TCQ 1'b0; gt_rx_is_skp1_q <= #TCQ 1'b0; end else begin reg_eios_detected <= #TCQ 1'b0; reg_symbol_after_eios <= #TCQ 1'b0; gt_rxcharisk_q <= #TCQ GT_RXCHARISK; gt_rxdata_q <= #TCQ GT_RXDATA; gt_rxvalid_q <= #TCQ GT_RXVALID; gt_rxelecidle_q <= #TCQ GT_RXELECIDLE; gt_rxelecidle_qq <= #TCQ gt_rxelecidle_q; gt_rx_status_q <= #TCQ GT_RX_STATUS; gt_rx_phy_status_q <= #TCQ GT_RX_PHY_STATUS; if (GT_RXCHARISK[0] && GT_RXDATA[7:0] == FTSOS_FTS) gt_rx_is_skp0_q <= #TCQ 1'b1; else gt_rx_is_skp0_q <= #TCQ 1'b0; if (GT_RXCHARISK[1] && GT_RXDATA[15:8] == FTSOS_FTS) gt_rx_is_skp1_q <= #TCQ 1'b1; else gt_rx_is_skp1_q <= #TCQ 1'b0; case ( state_eios_det ) EIOS_DET_IDL : begin if ((gt_rxcharisk_q[0]) && (gt_rxdata_q[7:0] == EIOS_COM) && (gt_rxcharisk_q[1]) && (gt_rxdata_q[15:8] == EIOS_IDL)) begin reg_state_eios_det <= #TCQ EIOS_DET_NO_STR0; reg_eios_detected <= #TCQ 1'b1; end else if ((gt_rxcharisk_q[1]) && (gt_rxdata_q[15:8] == EIOS_COM)) reg_state_eios_det <= #TCQ EIOS_DET_STR0; else reg_state_eios_det <= #TCQ EIOS_DET_IDL; end EIOS_DET_NO_STR0 : begin if ((gt_rxcharisk_q[0] && (gt_rxdata_q[7:0] == EIOS_IDL)) && (gt_rxcharisk_q[1] && (gt_rxdata_q[15:8] == EIOS_IDL))) reg_state_eios_det <= #TCQ EIOS_DET_DONE; else reg_state_eios_det <= #TCQ EIOS_DET_IDL; end EIOS_DET_STR0 : begin if ((gt_rxcharisk_q[0] && (gt_rxdata_q[7:0] == EIOS_IDL)) && (gt_rxcharisk_q[1] && (gt_rxdata_q[15:8] == EIOS_IDL))) begin reg_state_eios_det <= #TCQ EIOS_DET_STR1; reg_eios_detected <= #TCQ 1'b1; reg_symbol_after_eios <= #TCQ 1'b1; end else reg_state_eios_det <= #TCQ EIOS_DET_IDL; end EIOS_DET_STR1 : begin if ((gt_rxcharisk_q[0]) && (gt_rxdata_q[7:0] == EIOS_IDL)) reg_state_eios_det <= #TCQ EIOS_DET_DONE; else reg_state_eios_det <= #TCQ EIOS_DET_IDL; end EIOS_DET_DONE : begin reg_state_eios_det <= #TCQ EIOS_DET_IDL; end endcase end end assign state_eios_det = reg_state_eios_det; assign eios_detected = reg_eios_detected; assign symbol_after_eios = reg_symbol_after_eios; // user_rxvalid generation always @(posedge USER_CLK) begin if (RESET) begin reg_state_rxvld_ei <= #TCQ USER_RXVLD_IDL; end else begin case ( state_rxvld_ei ) USER_RXVLD_IDL : begin if (eios_detected) reg_state_rxvld_ei <= #TCQ USER_RXVLD_EI; else reg_state_rxvld_ei <= #TCQ USER_RXVLD_IDL; end USER_RXVLD_EI : begin if (!gt_rxvalid_q) reg_state_rxvld_ei <= #TCQ USER_RXVLD_EI_DB0; else if (rxvld_fallback == 4'b1111) reg_state_rxvld_ei <= #TCQ USER_RXVLD_IDL; else reg_state_rxvld_ei <= #TCQ USER_RXVLD_EI; end USER_RXVLD_EI_DB0 : begin if (gt_rxvalid_q) reg_state_rxvld_ei <= #TCQ USER_RXVLD_EI_DB1; else if (!PLM_IN_L0) reg_state_rxvld_ei <= #TCQ USER_RXVLD_IDL; else reg_state_rxvld_ei <= #TCQ USER_RXVLD_EI_DB0; end USER_RXVLD_EI_DB1 : begin if (rxvld_count > CLK_COR_MIN_LAT) reg_state_rxvld_ei <= #TCQ USER_RXVLD_IDL; else reg_state_rxvld_ei <= #TCQ USER_RXVLD_EI_DB1; end endcase end end assign state_rxvld_ei = reg_state_rxvld_ei; // RxValid counter always @(posedge USER_CLK) begin if (RESET) begin reg_rxvld_count <= #TCQ 5'b00000; end else begin if ((gt_rxvalid_q) && (state_rxvld_ei == USER_RXVLD_EI_DB1)) reg_rxvld_count <= #TCQ reg_rxvld_count + 1'b1; else reg_rxvld_count <= #TCQ 5'b00000; end end assign rxvld_count = reg_rxvld_count; // RxValid fallback always @(posedge USER_CLK) begin if (RESET) begin reg_rxvld_fallback <= #TCQ 4'b0000; end else begin if (state_rxvld_ei == USER_RXVLD_EI) reg_rxvld_fallback <= #TCQ reg_rxvld_fallback + 1'b1; else reg_rxvld_fallback <= #TCQ 4'b0000; end end assign rxvld_fallback = reg_rxvld_fallback; // Delay pipe_rx_elec_idle SRL16E #(.INIT(0)) rx_elec_idle_delay (.Q(USER_RXELECIDLE), .D(gt_rxelecidle_q), .CLK(USER_CLK), .CE(1'b1), .A3(1'b1),.A2(1'b1),.A1(1'b1),.A0(1'b1)); reg awake_in_progress_q = 1'b0; reg awake_see_com_q = 1'b0; reg [3:0] awake_com_count_q = 4'b0000; wire awake_see_com_0 = GT_RXVALID & (gt_rxcharisk_q[0] && (gt_rxdata_q[7:0] == EIOS_COM)); wire awake_see_com_1 = GT_RXVALID & (gt_rxcharisk_q[1] && (gt_rxdata_q[15:8] == EIOS_COM)); wire awake_see_com = (awake_see_com_0 || awake_see_com_1) && ~awake_see_com_q; // Count 8 COMs, (not back-to-back), when waking up from electrical idle // but not for L0s (which is L0). wire awake_done = awake_in_progress_q && (awake_com_count_q[3:0] >= 4'hb); wire awake_start = (~gt_rxelecidle_q && gt_rxelecidle_qq) || PLM_IN_RS; wire awake_in_progress = awake_start || (~awake_done && awake_in_progress_q); wire [3:0] awake_com_count_inced = awake_com_count_q[3:0] + 4'b0001; wire [3:0] awake_com_count = (~awake_in_progress_q) ? 4'b0000 : (awake_start) ? 4'b0000 : (awake_see_com_q) ? awake_com_count_inced[3:0] : awake_com_count_q[3:0]; wire rst_l = ~RESET; always @(posedge USER_CLK) begin awake_see_com_q <= #TCQ (rst_l) ? awake_see_com : 1'b0; awake_in_progress_q <= #TCQ (rst_l) ? awake_in_progress : 1'b0; awake_com_count_q[3:0] <= #TCQ (rst_l) ? awake_com_count[3:0] : 4'h0; end assign USER_RXVALID = ((state_rxvld_ei == USER_RXVLD_IDL) && ~awake_in_progress_q) ? gt_rxvalid_q : 1'b0; assign USER_RXCHARISK[0] = USER_RXVALID ? gt_rxcharisk_q[0] : 1'b0; assign USER_RXCHARISK[1] = (USER_RXVALID && !symbol_after_eios) ? gt_rxcharisk_q[1] : 1'b0; assign USER_RXDATA[7:0] = (gt_rx_is_skp0_q) ? FTSOS_COM : gt_rxdata_q[7:0]; assign USER_RXDATA[15:8] = (gt_rx_is_skp1_q) ? FTSOS_COM : gt_rxdata_q[15:8]; assign USER_RX_STATUS = (state_rxvld_ei == USER_RXVLD_IDL) ? gt_rx_status_q : 3'b000; assign USER_RX_PHY_STATUS = gt_rx_phy_status_q; endmodule