赞
踩
XILINX的 serdes GT IP真的是够复杂的,生成的例子也是复杂,而且为了适配各种情况,代码里很多冗余的东西,发送部分比较简单 ,接收部分有点繁琐,我做了点注释,这里的只做的GTP的,GTX的自己看吧。
- ///
- // ____ ____
- // / /\/ /
- // /___/ \ / Vendor: Xilinx
- // \ \ \/ Version : 3.6
- // \ \ Application : 7 Series FPGAs Transceivers Wizard
- // / / Filename : gtwizard_0_gt_frame_check.v
- // /___/ /\
- // \ \ / \
- // \___\/\___\
- //
- //
- // Module gtwizard_0_GT_FRAME_CHECK
- // 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
-
- //***********************************Entity Declaration************************
- (* DowngradeIPIdentifiedWarnings="yes" *)
- module gtwizard_0_GT_FRAME_CHECK #
- (
- // parameter to set the number of words in the BRAM
- parameter RX_DATA_WIDTH = 64,
- parameter RXCTRL_WIDTH = 2,
- parameter WORDS_IN_BRAM = 512,
- parameter CHANBOND_SEQ_LEN = 1,
- parameter COMMA_DOUBLE = 16'hf628,
- parameter START_OF_PACKET_CHAR = 64'h00000000000000fb
- )
- (
- // User Interface
- input wire [(RX_DATA_WIDTH-1):0] RX_DATA_IN,
- input wire [(RXCTRL_WIDTH-1):0] RXCTRL_IN,
-
- output reg RXENPCOMMADET_OUT, // 未用,高电平有效信号,可实现字节边界对齐检测到plus COMMA模式时进行处理。
- output reg RXENMCOMMADET_OUT, // 未用,高电平有效信号,可实现字节边界对齐检测到minus COMMA模式时进行处理。
- output reg RX_ENCHAN_SYNC_OUT, // 未用,驱动mgt的enchansync端口进行通道绑定
- input wire RX_CHANBOND_SEQ_IN, // 输入通道绑定序列,不绑定时为0
-
- // Control Interface
- input wire INC_IN, // 未用
- output wire INC_OUT, // 非独立的收发测试时输出已开始进行COMMA检测,指示发送端地址递增
- output wire PATTERN_MATCHB_OUT, // COMMA不匹配
- input wire RESET_ON_ERROR_IN, // 通过将PATTERN_MATCHB_OUT输出给外部,由此产生出错后的复位
-
-
- // Error Monitoring
- output wire [7:0] ERROR_COUNT_OUT, // 错误数
-
- // Track Data
- output wire TRACK_DATA_OUT, // 指示接收到的数据是否符合预期
-
- output wire RX_SLIDE, // 在对齐时要求GT滑动
- // System Interface
- input wire USER_CLK,
- input wire SYSTEM_RESET
- );
-
-
- //***************************Internal Register Declarations********************
-
- reg reset_on_error_in_r;
- reg reset_on_error_in_r2;
- (* ASYNC_REG = "TRUE" *) (* keep = "true" *)reg system_reset_r;
- (* ASYNC_REG = "TRUE" *) (* keep = "true" *)reg system_reset_r2;
-
- reg begin_r;
- reg data_error_detected_r;
- reg [8:0] error_count_r;
- reg error_detected_r;
- reg [9:0] read_counter_i;
-
- reg [79:0] rom [0:511];
-
- reg [(RX_DATA_WIDTH-1):0] rx_data_r;
- reg [(RX_DATA_WIDTH-1):0] rx_data_r_track;
-
- reg start_of_packet_detected_r;
- reg track_data_r;
- reg track_data_r2;
- reg track_data_r3;
- reg [79:0] rx_data_ram_r;
- reg [(RX_DATA_WIDTH-1):0] rx_data_r2;
- reg [(RX_DATA_WIDTH-1):0] rx_data_r3;
- reg [(RX_DATA_WIDTH-1):0] rx_data_r4;
- reg [(RX_DATA_WIDTH-1):0] rx_data_r5;
- reg [(RX_DATA_WIDTH-1):0] rx_data_r6;
- reg [(RXCTRL_WIDTH-1):0] rxctrl_r;
- reg [(RXCTRL_WIDTH-1):0] rxctrl_r2;
- reg [(RXCTRL_WIDTH-1):0] rxctrl_r3;
-
- reg rx_chanbond_seq_r;
- reg rx_chanbond_seq_r2;
- reg rx_chanbond_seq_r3;
-
- reg idle_slip_r;
- reg slip_assert_r;
- reg wait_state_r;
- reg bit_align_r;
- reg [6:0] wait_before_slip_r;
- reg [6:0] wait_before_init_r;
-
- reg [1:0] sel;
- //*********************************Wire Declarations***************************
-
- wire [(RX_DATA_WIDTH-1):0] bram_data_r;
- wire error_detected_c;
- wire next_begin_c;
- wire next_data_error_detected_c;
- wire next_track_data_c;
- wire start_of_packet_detected_c;
- wire chanbondseq_in_data;
- wire input_to_chanbond_data_i;
- wire input_to_chanbond_reg_i;
- wire [(CHANBOND_SEQ_LEN-1):0] rx_chanbond_reg;
- wire rxdata_or;
- wire count_slip_complete_c;
- wire next_idle_slip_c;
- wire next_slip_assert_c;
- wire wait_state_c;
- wire [(RX_DATA_WIDTH-1):0] rx_data_aligned;
- wire rx_data_has_start_char_c;
- wire tied_to_ground_i;
- wire [31:0] tied_to_ground_vec_i;
- wire tied_to_vcc_i;
-
- //*********************************Main Body of Code***************************
-
- //_______________________ Static signal Assigments _______________________
-
- assign tied_to_ground_i = 1'b0;
- assign tied_to_ground_vec_i = 32'h0000;
- assign tied_to_vcc_i = 1'b1;
-
- //___________ synchronizing the async reset for ease of timing simulation ________
- always@(posedge USER_CLK)
- begin
- system_reset_r <= `DLY SYSTEM_RESET;
- system_reset_r2 <= `DLY system_reset_r;
- end
- always@(posedge USER_CLK)
- begin
- reset_on_error_in_r <= `DLY RESET_ON_ERROR_IN;
- reset_on_error_in_r2 <= `DLY reset_on_error_in_r;
- end
-
- //______________________ Register RXDATA once to ease timing ______________
-
- always @(posedge USER_CLK)
- begin
- rx_data_r <= `DLY RX_DATA_IN;
- rx_data_r2 <= `DLY rx_data_r;
- end
-
- always @(posedge USER_CLK)
- begin
- rxctrl_r <= `DLY RXCTRL_IN;
- end
-
- //________________________________ State machine __________________________
-
- // State registers
- always @(posedge USER_CLK)
- if(system_reset_r2)
- {begin_r,track_data_r,data_error_detected_r} <= `DLY 3'b100;
- else
- begin
- begin_r <= `DLY next_begin_c;
- track_data_r <= `DLY next_track_data_c;
- data_error_detected_r <= `DLY next_data_error_detected_c;
- end
-
- // Next state logic
- assign next_begin_c = (begin_r && !start_of_packet_detected_r) // 产生启动请求信号,在该信号复位为高后且未收到已开始数据检测的指示时保持为高,或数据出错时
- || data_error_detected_r ;
-
- assign next_track_data_c = (begin_r && start_of_packet_detected_r) // 产生检测数据跟踪请求,在启动为高后且收到开始检测到有效数据的指示时保持为高,或者已启动数据跟踪且未出错时
- || (track_data_r && !error_detected_r);
-
- assign next_data_error_detected_c = (track_data_r && error_detected_r); // 已启动跟踪,且检测到了错误
-
- assign start_of_packet_detected_c = rx_data_has_start_char_c; // 已开始检测到有效数据
-
- always @(posedge USER_CLK)
- start_of_packet_detected_r <= `DLY start_of_packet_detected_c;
-
- // Registering for timing
- always @(posedge USER_CLK)
- track_data_r2 <= `DLY track_data_r;
-
- always @(posedge USER_CLK)
- track_data_r3 <= `DLY track_data_r2;
-
- //______________________________ Capture incoming data ____________________
- // 根据COMMA出现的位置将32b重新对齐
- always @(posedge USER_CLK)
- begin
- if(system_reset_r2) rx_data_r3 <= 'h0;
- else
- begin
- if(sel == 2'b01)
- begin
- rx_data_r3 <= `DLY {rx_data_r[(RX_DATA_WIDTH/4-1):0],rx_data_r2[(RX_DATA_WIDTH - 1):RX_DATA_WIDTH/4]};
- end
- else if(sel == 2'b10)
- begin
- rx_data_r3 <= `DLY {rx_data_r[(2*RX_DATA_WIDTH/4-1):0],rx_data_r2[(RX_DATA_WIDTH - 1):2*RX_DATA_WIDTH/4]};
- end
- else if(sel == 2'b11)
- begin
- rx_data_r3 <= `DLY {rx_data_r[(3*RX_DATA_WIDTH/4 - 1):0],rx_data_r2[(RX_DATA_WIDTH-1):3*RX_DATA_WIDTH/4]};
- end
- else rx_data_r3 <= `DLY rx_data_r2;
- end
- end
-
- always @(posedge USER_CLK)
- begin
- if(system_reset_r2)
- begin
- rx_data_r4 <= `DLY 'h0;
- rx_data_r5 <= `DLY 'h0;
- rx_data_r6 <= `DLY 'h0;
- rx_data_r_track <= `DLY 'h0;
- end
- else
- begin
- rx_data_r4 <= `DLY rx_data_r3;
- rx_data_r5 <= `DLY rx_data_r4;
- rx_data_r6 <= `DLY rx_data_r5;
- rx_data_r_track <= `DLY rx_data_r6;
- end
- end
-
- always @(posedge USER_CLK)
- begin
- if(system_reset_r2)
- begin
- rxctrl_r2 <= `DLY 'h0;
- rxctrl_r3 <= `DLY 'h0;
- end
- else
- begin
- rxctrl_r2 <= `DLY rxctrl_r;
- rxctrl_r3 <= `DLY rxctrl_r2;
- end
- end
- assign rx_data_aligned = rx_data_r3;
-
- //___________________________ Code for Channel bonding ____________________
- // code to prevent checking of clock correction sequences for the start of packet char
- always @(posedge USER_CLK)
- begin
- rx_chanbond_seq_r <= `DLY RX_CHANBOND_SEQ_IN;
- rx_chanbond_seq_r2 <= `DLY rx_chanbond_seq_r;
- rx_chanbond_seq_r3 <= `DLY rx_chanbond_seq_r2;
- end
-
- assign input_to_chanbond_reg_i = rx_chanbond_seq_r2; //一直为0
- assign input_to_chanbond_data_i = tied_to_ground_i;
-
-
- //______________ Code for Bit Slipping Logic______________
-
- assign rxdata_or = |(rx_data_r|rx_data_r2|rx_data_r3); // 通道有收到数据
-
- // State registers
- always @(posedge USER_CLK)
- if( (system_reset_r2 == 1'b1) | (wait_before_init_r[6] == 1'b0) | (rxdata_or == 1'b0) )
- {idle_slip_r,slip_assert_r,wait_state_r} <= `DLY 3'b100;
- else
- begin
- idle_slip_r <= `DLY next_idle_slip_c;
- slip_assert_r <= `DLY next_slip_assert_c;
- wait_state_r <= `DLY wait_state_c;
- end
-
- // Next state logic
- assign next_idle_slip_c = (idle_slip_r & bit_align_r) | (wait_state_r & count_slip_complete_c); // slip操作空闲信号,当复为后且bit已对齐时,或者已完成执行滑窗后的等待
-
- assign next_slip_assert_c = (idle_slip_r & !bit_align_r); // 继续执行slip,上一slip操作已完成,但bit仍未对齐
-
- assign wait_state_c = (slip_assert_r) | (wait_state_r & !count_slip_complete_c); // slip请求已产生,但是等待操作还未完成,则持续等待
-
- //_______ Counter for waiting clock cycles after RXSLIDE________
- always @(posedge USER_CLK)
- begin
- if (!wait_state_r)
- wait_before_slip_r <= `DLY 7'b000000;
- else
- wait_before_slip_r <= `DLY wait_before_slip_r + 1'b1; // slip操作等待计时器
- end
-
- //_______ Counter for waiting clock cycles before starting RXSLIDE operation________
- //_______ Wait for 64 clock cycles to see if the RXDATA is already byte aligned. If not, start RXSLIDE operation
- always @(posedge USER_CLK)
- begin
- if( (system_reset_r2 == 1'b1) | (rxdata_or == 1'b0) )
- wait_before_init_r <= `DLY 7'b0000000;
- else if (wait_before_init_r[6] == 1'b0) // 在启动接收前等待64clk
- wait_before_init_r <= `DLY wait_before_init_r + 1'b1;
- end
-
- assign count_slip_complete_c = wait_before_slip_r[6];
-
- always @(posedge USER_CLK)
- begin
- if( (system_reset_r2 == 1'b1) | (rxdata_or == 1'b0) ) begin
- bit_align_r <= 1'b0;
- end else begin
- if( ({rx_data_r[23:0],rx_data_r2[31:24]} == START_OF_PACKET_CHAR) || ({rx_data_r[15:0],rx_data_r2[31:16]} == START_OF_PACKET_CHAR)
- || ({rx_data_r[7:0],rx_data_r2[31:8]} == START_OF_PACKET_CHAR) || (rx_data_r[31:0]== START_OF_PACKET_CHAR) )
- begin
- bit_align_r <= 1'b1; // 比较COMMA所有可能存在的4种情况以确定bit对齐
- end
- end
- end
-
- // Comma realignment logic might be needed. 4 levels of registering for RXDATA to meet timing
- // In 4 Byte scenario, when align_comma_word=1, Comma can appear on any of the four bytes.
- // { BYTE3 | BYTE2 | BYTE1 | BYTE0 } - Comma can appear on BYTE0/1/2/3
- // If Comma appears on BYTE1/2/3, RX_DATA is realigned so that Comma appears on BYTE0 in rx_data_r_track
- always @(posedge USER_CLK)
- begin
- if(reset_on_error_in_r2 || system_reset_r2) sel <= 2'b00;
- else if (begin_r && !rx_chanbond_seq_r)
- begin
- // if Comma appears on BYTE3 ..
- if((rx_data_r[(RX_DATA_WIDTH - 1) : 3*RX_DATA_WIDTH/4] == START_OF_PACKET_CHAR[7:0]) && rxctrl_r[3]) // rxctrl_r 指示COMMA出现的位置,并比较收的包头是否匹配
- sel <= 2'b11;
- // if Comma appears on BYTE2 ..
- else if((rx_data_r[(3*RX_DATA_WIDTH/4 - 1):2*RX_DATA_WIDTH/4] == START_OF_PACKET_CHAR[7:0]) && rxctrl_r[2])
- begin
- sel <= 2'b10;
- end
- // if Comma appears on BYTE1 ..
- else if((rx_data_r[(2*RX_DATA_WIDTH/4 - 1):RX_DATA_WIDTH/4] == START_OF_PACKET_CHAR[7:0]) && rxctrl_r[1])
- begin
- sel <= 2'b01;
- end
- // if Comma appears on BYTE0 ..
- else if((rx_data_r[(RX_DATA_WIDTH/4 - 1):0] == START_OF_PACKET_CHAR[7:0]) && rxctrl_r[0])
- begin
- sel <= 2'b00;
- end
- end
- end
-
- //___________________________ Code for Channel bonding ____________________
- // code to prevent checking of clock correction sequences for the start of packet char
- genvar i;
- generate
- for (i=0;i<CHANBOND_SEQ_LEN ;i=i+1)
- begin:register_chan_seq
- if(i==0)
- FD rx_chanbond_reg_0 ( .Q (rx_chanbond_reg[i]), .D (input_to_chanbond_reg_i), .C(USER_CLK));
- else
- FD rx_chanbond_reg_i ( .Q (rx_chanbond_reg[i]), .D (rx_chanbond_reg[i-1]), .C(USER_CLK));
- end
- endgenerate
-
- assign chanbondseq_in_data = |rx_chanbond_reg || input_to_chanbond_data_i; // 未绑定始终为0
-
-
- assign rx_data_has_start_char_c = (rx_data_aligned[7:0] == START_OF_PACKET_CHAR[7:0]) && !chanbondseq_in_data && (|rxctrl_r3); // 只要对齐后的数据有一byte匹配
-
-
- //_____________________________ Assign output ports _______________________
- //assign TRACK_DATA_OUT = track_data_r;
-
- assign RX_SLIDE = slip_assert_r; // 输出slip信号
-
- // Drive the enpcommaalign port of the gt for alignment
- // Active-High signal that enables the byte boundary alignment process when the plus comma pattern is detected.
- always @(posedge USER_CLK)
- if(system_reset_r2) RXENPCOMMADET_OUT <= `DLY 1'b0;
- else RXENPCOMMADET_OUT <= `DLY 1'b1;
-
- // Drive the enmcommaalign port of the gt for alignment
- // Active-High signal that enables the byte boundary alignment process when the minus comma pattern is detected.
- always @(posedge USER_CLK)
- if(system_reset_r2) RXENMCOMMADET_OUT <= `DLY 1'b0;
- else RXENMCOMMADET_OUT <= `DLY 1'b1;
-
- assign INC_OUT = start_of_packet_detected_c;
-
- assign PATTERN_MATCHB_OUT = data_error_detected_r;
-
- // Drive the enchansync port of the mgt for channel bonding
- always @(posedge USER_CLK)
- if(system_reset_r2) RX_ENCHAN_SYNC_OUT <= `DLY 1'b0;
- else RX_ENCHAN_SYNC_OUT <= `DLY 1'b1;
-
- //___________________________ Check incoming data for errors ______________
-
- //An error is detected when data read for the BRAM does not match the incoming data
- assign error_detected_c = track_data_r3 && (rx_data_r_track != bram_data_r); // 数据与ROM中不匹配
-
- //We register the error_detected signal for use with the error counter logic
- always @(posedge USER_CLK)
- if(!track_data_r)
- error_detected_r <= `DLY 1'b0;
- else
- error_detected_r <= `DLY error_detected_c;
-
- //We count the total number of errors we detect. By keeping a count we make it less likely that we will miss
- //errors we did not directly observe.
- always @(posedge USER_CLK)
- if(system_reset_r2)
- error_count_r <= `DLY 9'd0;
- else if(error_detected_r)
- error_count_r <= `DLY error_count_r + 1;
-
- //Here we connect the lower 8 bits of the count (the MSbit is used only to check when the counter reaches
- //max value) to the module output
- assign ERROR_COUNT_OUT = error_count_r[7:0];
-
- localparam ST_LINK_DOWN = 1'b0;
- localparam ST_LINK_UP = 1'b1;
- reg sm_link = ST_LINK_DOWN;
- reg [6:0] link_ctr = 7'd0;
-
- always @(posedge USER_CLK) begin
- if(!track_data_r)
- sm_link <= ST_LINK_DOWN;
- else
- case (sm_link)
- // The link is considered to be down when the link counter initially has a value less than 67. When the link is
- // down, the counter is incremented on each cycle where all PRBS bits match, but reset whenever any PRBS mismatch
- // occurs. When the link counter reaches 67, transition to the link up state.
- ST_LINK_DOWN: begin
- if (error_detected_r !== 1'b0) begin
- link_ctr <= 7'd0;
- end
- else begin
- if (link_ctr < 7'd67)
- link_ctr <= link_ctr + 7'd1;
- else
- sm_link <= ST_LINK_UP;
- end
- end
-
- // When the link is up, the link counter is decreased by 34 whenever any PRBS mismatch occurs, but is increased by
- // only 1 on each cycle where all PRBS bits match, up to its saturation point of 67. If the link counter reaches
- // 0 (including rollover protection), transition to the link down state.
- ST_LINK_UP: begin
- if (error_detected_r !== 1'b0) begin
- if (link_ctr > 7'd33) begin
- link_ctr <= link_ctr - 7'd34;
- if (link_ctr == 7'd34)
- sm_link <= ST_LINK_DOWN;
- end
- else begin
- link_ctr <= 7'd0;
- sm_link <= ST_LINK_DOWN;
- end
- end
- else begin
- if (link_ctr < 7'd67)
- link_ctr <= link_ctr + 7'd1;
- end
- end
- endcase
- end
-
- assign TRACK_DATA_OUT = sm_link;
- //____________________________ Counter to read from BRAM __________________________
- always @(posedge USER_CLK)
- if(system_reset_r2 || (read_counter_i == (WORDS_IN_BRAM-1)))
- begin
- read_counter_i <= `DLY 10'd0;
- end
- else if (start_of_packet_detected_r && !track_data_r)
- begin
- read_counter_i <= `DLY 10'd0;
- end
- else
- begin
- read_counter_i <= `DLY read_counter_i + 10'd1;
- end
-
- //________________________________ BRAM Inference Logic _____________________________
-
- //Array slice from dat file to compare against receive data
- generate
- if(RX_DATA_WIDTH==80)
- begin : datapath_80
- assign bram_data_r = rx_data_ram_r[(RX_DATA_WIDTH-1):0];
- end
- else
- begin : datapath_16_20_32_40_64
- assign bram_data_r = rx_data_ram_r[(16+RX_DATA_WIDTH-1):16];
- end
- endgenerate
-
- `ifdef SIM
- initial
- begin
- $readmemh("gt_rom_init_rx.dat",rom,0,511);
- end
-
- always @(posedge USER_CLK)
- rx_data_ram_r <= `DLY rom[read_counter_i];
- `else
- always @(posedge USER_CLK)
- rx_data_ram_r <= 'haa5555aa;//`DLY rom[read_counter_i];
- `endif
-
- endmodule

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。