//------------------------------------------------------------------------------ // (c) Copyright 2013-2015 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. //------------------------------------------------------------------------------ // *************************** // * DO NOT MODIFY THIS FILE * // *************************** `timescale 1ps/1ps module gtwizard_ultrascale_v1_7_9_gthe4_cpll_cal_rx # ( parameter C_SIM_CPLL_CAL_BYPASS = 1'b1, parameter SIM_RESET_SPEEDUP = "TRUE", parameter CPLL_CAL_ONLY_TX = 1, parameter C_FREERUN_FREQUENCY = 100 )( // control signals input wire [17:0] RXOUTCLK_PERIOD_IN, input wire [17:0] CNT_TOL_IN, input wire [15:0] FREQ_COUNT_WINDOW_IN, // User Interface input wire RESET_IN, input wire CLK_IN, input wire USER_RXPROGDIVRESET_IN, output wire USER_RXPRGDIVRESETDONE_OUT, output wire USER_RXPMARESETDONE_OUT, input wire [2:0] USER_RXOUTCLKSEL_IN, input wire USER_RXOUTCLK_BUFG_CE_IN, input wire USER_RXOUTCLK_BUFG_CLR_IN, output reg USER_CPLLLOCK_OUT, input wire USER_GTRXRESET_IN, input wire USER_RXCDRHOLD_IN, input wire USER_RXPMARESET_IN, // Debug Interface output wire CPLL_CAL_FAIL, output wire CPLL_CAL_DONE, output wire [15:0] DEBUG_OUT, output wire [17:0] CAL_FREQ_CNT, input [3:0] REPEAT_RESET_LIMIT, // GT Interface input wire GTHE4_RXOUTCLK_IN, input wire GTHE4_CPLLLOCK_IN, output wire GTHE4_CPLLRESET_OUT, output wire GTHE4_CPLLPD_OUT, output wire GTHE4_RXPROGDIVRESET_OUT, output wire [2:0] GTHE4_RXOUTCLKSEL_OUT, input wire GTHE4_RXPRGDIVRESETDONE_IN, output wire [9:0] GTHE4_CHANNEL_DRPADDR_OUT, output wire [15:0] GTHE4_CHANNEL_DRPDI_OUT, output wire GTHE4_CHANNEL_DRPEN_OUT, output wire GTHE4_CHANNEL_DRPWE_OUT, input wire GTHE4_CHANNEL_DRPRDY_IN, input wire [15:0] GTHE4_CHANNEL_DRPDO_IN, output wire GTHE4_GTRXRESET_OUT, output wire GTHE4_RXPMARESET_OUT, output wire GTHE4_RXCDRHOLD_OUT, input wire GTHE4_RXPMARESETDONE_IN, output wire DONE ); generate if (CPLL_CAL_ONLY_TX == 1) begin: gen_cal_rx_dis assign GTHE4_RXPROGDIVRESET_OUT = USER_RXPROGDIVRESET_IN; assign GTHE4_GTRXRESET_OUT = USER_GTRXRESET_IN; assign GTHE4_RXOUTCLKSEL_OUT = USER_RXOUTCLKSEL_IN; assign GTHE4_RXCDRHOLD_OUT = USER_RXCDRHOLD_IN; assign GTHE4_RXPMARESET_OUT = USER_RXPMARESET_IN; assign USER_RXPRGDIVRESETDONE_OUT = GTHE4_RXPRGDIVRESETDONE_IN; assign USER_RXPMARESETDONE_OUT = GTHE4_RXPMARESETDONE_IN; assign CPLL_CAL_DONE = 1'd0; assign CPLL_CAL_FAIL = 1'd0; assign DONE = 1'd1; assign GTHE4_CHANNEL_DRPEN_OUT = 1'd0; assign GTHE4_CHANNEL_DRPWE_OUT = 1'd0; assign GTHE4_CPLLPD_OUT = 1'd0; assign GTHE4_CPLLRESET_OUT = 1'd0; assign DEBUG_OUT = 16'd0; assign GTHE4_CHANNEL_DRPDI_OUT = 16'd0; assign CAL_FREQ_CNT = 18'd0; assign GTHE4_CHANNEL_DRPADDR_OUT = 10'd0; always @(posedge CLK_IN) begin if(RESET_IN) USER_CPLLLOCK_OUT <= 1'b0; else USER_CPLLLOCK_OUT <= 1'b0; end end else begin: gen_cal_rx_en //DRP FSM localparam DRP_WAIT = 0; localparam DRP_READ = 1; localparam DRP_READ_ACK = 2; localparam DRP_MODIFY = 3; localparam DRP_WRITE = 4; localparam DRP_WRITE_ACK = 5; localparam DRP_DONE = 6; localparam RESET = 0; localparam READ_X114 = 1; localparam CHECK_X114_STATUS = 2; localparam READ_PROGDIV_CFG = 3; localparam SAVE_PROGDIV_CFG = 4; localparam MODIFY_PROGDIV = 5; localparam MODIFY_RXOUTCLK_SEL = 6; localparam ASSERT_RXCDRHOLD = 7; localparam ASSERT_CPLLPD = 8; localparam DEASSERT_CPLLPD = 9; localparam ASSERT_CPLLRESET = 10; localparam DEASSERT_CPLLRESET = 11; localparam WAIT_GTCPLLLOCK = 12; localparam ASSERT_GTRXRESET = 13; localparam WAIT_RXPMARESETDONE = 14; localparam WAIT_RXPMARESETDONE_DEASSERT = 15; localparam WAIT_RXPMARESETDONE_2 = 16; localparam ASSERT_PROGDIVRESET = 17; localparam WAIT_PRGDIVRESETDONE = 18; localparam CHECK_FREQ = 19; localparam RESTORE_READ_X114 = 20; localparam RESTORE_PROGDIV = 21; localparam CLEAR_FLAG_x114 = 22; localparam WAIT_GTCPLLLOCK2 = 23; localparam ASSERT_PROGDIVRESET2 = 24; localparam WAIT_PRGDIVRESETDONE2= 25; localparam CAL_FAIL = 26; localparam CAL_DONE = 27; reg [31:0] cpll_cal_state = 31'd0; wire [4:0] cpll_cal_state_bin; reg [6:0] drp_state = 7'd1; wire drp_done; reg [9:0] daddr = 10'd0; reg [15:0] di = 16'd0; wire drdy; wire [15:0] dout; reg den = 1'b0; reg dwe = 1'b0; reg wr = 1'b0; reg rd = 1'b0; reg [15:0] di_msk; reg [15:0] mask; reg [24:0] wait_ctr; reg [3:0] repeat_ctr; reg [15:0] progdiv_cfg_store = 16'd0; reg mask_user_in = 1'b0; reg cpllreset_int = 1'b0; reg cpllpd_int = 1'b0; reg rxprogdivreset_int = 1'b0; reg rxcdrhold_int = 1'b0; reg gtrxreset_int = 1'b0; reg [2:0] rxoutclksel_int = 3'b000; reg cal_fail_store = 1'b0; reg status_store = 1'b0; wire den_i; wire dwe_i; //All these need to be based on CLK_IN frequency (free_run) localparam [24:0] SYNTH_WAIT_ASSERT_CPLLRESET = (1000 * C_FREERUN_FREQUENCY ); // 1 ms localparam [24:0] SYNTH_WAIT_CPLLLOCK = (1000 * C_FREERUN_FREQUENCY ); // 1 ms localparam [24:0] SYNTH_WAIT_DEASSERT_CPLLRESET = (100 * C_FREERUN_FREQUENCY ); // 100 us localparam [24:0] SYNTH_WAIT_ASSERT_PROGDIVRESET = C_FREERUN_FREQUENCY ; // 1 us localparam [24:0] SIM_WAIT_ASSERT_CPLLRESET = SYNTH_WAIT_ASSERT_CPLLRESET/10; localparam [24:0] SIM_WAIT_CPLLLOCK = SYNTH_WAIT_CPLLLOCK/10; localparam [24:0] SIM_WAIT_DEASSERT_CPLLRESET = SYNTH_WAIT_DEASSERT_CPLLRESET/10; localparam [24:0] SIM_WAIT_ASSERT_PROGDIVRESET = SYNTH_WAIT_ASSERT_PROGDIVRESET/10; localparam [40:1] SIM_RESET_SPEEDUP_REG = SIM_RESET_SPEEDUP; localparam [4:0] WAIT_WIDTH_PROGDIVRESET = 5'd25; // >= 100 ns localparam [24:0] WAIT_ASSERT_CPLLRESET = //pragma translate_off (SIM_RESET_SPEEDUP_REG == "TRUE") ? SIM_WAIT_ASSERT_CPLLRESET : //pragma translate_on SYNTH_WAIT_ASSERT_CPLLRESET; localparam [4:0] WAIT_ASSERT_CPLLPD = 5'd25; // >= 100 ns localparam [24:0] WAIT_DEASSERT_CPLLRESET = //pragma translate_off (SIM_RESET_SPEEDUP_REG == "TRUE") ? SIM_WAIT_DEASSERT_CPLLRESET : //pragma translate_on SYNTH_WAIT_DEASSERT_CPLLRESET; localparam [24:0] WAIT_CPLLLOCK = //pragma translate_off (SIM_RESET_SPEEDUP_REG == "TRUE") ? SIM_WAIT_CPLLLOCK : //pragma translate_on SYNTH_WAIT_CPLLLOCK; localparam [24:0] WAIT_ASSERT_PROGDIVRESET = //pragma translate_off (SIM_RESET_SPEEDUP_REG == "TRUE") ? SIM_WAIT_ASSERT_PROGDIVRESET : //pragma translate_on SYNTH_WAIT_ASSERT_PROGDIVRESET; localparam [15:0] MOD_PROGDIV_CFG = 16'hE062; //divider 20 localparam [2:0] MOD_RXOUTCLK_SEL = 3'b101; localparam [9:0] ADDR_RX_PROGDIV_CFG = 10'h0C6; localparam [9:0] ADDR_X114 = 10'h114; // Drive RXOUTCLK with BUFG_GT-buffered source clock, divider = 1 wire rxoutclkmon; //assign rxoutclkmon = GTHE4_RXOUTCLK_IN; BUFG_GT bufg_gt_rxoutclkmon_inst ( .CE (USER_RXOUTCLK_BUFG_CE_IN), .CEMASK (1'b1), .CLR (USER_RXOUTCLK_BUFG_CLR_IN), .CLRMASK (1'b1), .DIV (3'b000), .I (GTHE4_RXOUTCLK_IN), .O (rxoutclkmon) ); wire gthe4_cplllock_sync; gtwizard_ultrascale_v1_7_9_bit_synchronizer bit_synchronizer_cplllock_inst ( .clk_in (CLK_IN), .i_in (GTHE4_CPLLLOCK_IN), .o_out (gthe4_cplllock_sync) ); wire gthe4_rxpmaresetdone_sync; gtwizard_ultrascale_v1_7_9_bit_synchronizer bit_synchronizer_rxpmaresetdone_inst ( .clk_in (CLK_IN), .i_in (GTHE4_RXPMARESETDONE_IN), .o_out (gthe4_rxpmaresetdone_sync) ); wire gthe4_rxprgdivresetdone_sync; gtwizard_ultrascale_v1_7_9_bit_synchronizer bit_synchronizer_rxprgdivresetdone_inst ( .clk_in (CLK_IN), .i_in (GTHE4_RXPRGDIVRESETDONE_IN), .o_out (gthe4_rxprgdivresetdone_sync) ); assign GTHE4_CPLLRESET_OUT = cpllreset_int; assign GTHE4_CPLLPD_OUT = cpllpd_int; always @(posedge CLK_IN) begin if (mask_user_in | cpll_cal_state[CAL_FAIL] | cpll_cal_state[RESET] | RESET_IN) USER_CPLLLOCK_OUT <= 1'b0; else USER_CPLLLOCK_OUT <= gthe4_cplllock_sync; end assign GTHE4_RXPROGDIVRESET_OUT = mask_user_in ? rxprogdivreset_int : USER_RXPROGDIVRESET_IN; assign GTHE4_GTRXRESET_OUT = mask_user_in ? gtrxreset_int : USER_GTRXRESET_IN; assign GTHE4_RXOUTCLKSEL_OUT = mask_user_in ? rxoutclksel_int : USER_RXOUTCLKSEL_IN; assign GTHE4_RXCDRHOLD_OUT = mask_user_in ? rxcdrhold_int : USER_RXCDRHOLD_IN; assign GTHE4_RXPMARESET_OUT = mask_user_in ? 1'b0 : USER_RXPMARESET_IN; assign USER_RXPRGDIVRESETDONE_OUT = mask_user_in ? 1'b0 : GTHE4_RXPRGDIVRESETDONE_IN; assign USER_RXPMARESETDONE_OUT = mask_user_in ? 1'b0 : GTHE4_RXPMARESETDONE_IN; // frequency counter for rxoutclk wire [17:0] rxoutclk_freq_cnt; reg freq_counter_rst = 1'b1; wire freq_cnt_done; gtwizard_ultrascale_v1_7_9_gthe4_cpll_cal_freq_counter U_RXOUTCLK_FREQ_COUNTER ( .freq_cnt_o(rxoutclk_freq_cnt), .done_o(freq_cnt_done), .rst_i(freq_counter_rst), .test_term_cnt_i(FREQ_COUNT_WINDOW_IN), .ref_clk_i(CLK_IN), .test_clk_i(rxoutclkmon) ); //Debug signals assign DEBUG_OUT = {cpllreset_int,cpllpd_int,gthe4_cplllock_sync,1'b0,freq_cnt_done,freq_counter_rst,mask_user_in,cpll_cal_state_bin,repeat_ctr}; assign CPLL_CAL_FAIL = cpll_cal_state[CAL_FAIL]; assign CPLL_CAL_DONE = cpll_cal_state[CAL_DONE]; assign CAL_FREQ_CNT = rxoutclk_freq_cnt; assign DONE = cpll_cal_state[CAL_DONE] | cpll_cal_state[RESET]; //pragma translate_off if (C_SIM_CPLL_CAL_BYPASS == 1'b1) begin: gen_sim_cpll_cal_bypass_gthe4 //CPLL CAL FSM for simulation always @(posedge CLK_IN) begin if (RESET_IN) begin cpll_cal_state <= 0; cpll_cal_state[RESET] <= 1'b1; cpllreset_int <= 1'b0; cpllpd_int <= 1'b0; rxprogdivreset_int <= 1'b0; mask_user_in <= 1'b0; wr <= 1'b0; rd <= 1'b0; rxcdrhold_int <= 1'b0; gtrxreset_int <= 1'b0; end else begin cpll_cal_state <= 0; case(1'b1) // synthesis parallel_case full_case cpll_cal_state[RESET]: begin wait_ctr <= 25'd0; repeat_ctr <= 4'd0; mask_user_in <= 1'b1; di_msk <= 16'b0000_0000_0000_0000; cpll_cal_state[READ_X114] <= 1'b1; end cpll_cal_state[READ_X114]: begin mask_user_in <= 1'b1; rd <= 1'b1; if (drp_done) begin rd <= 1'b0; status_store <= dout[15]; cpll_cal_state[CHECK_X114_STATUS] <= 1'b1; end else cpll_cal_state[READ_X114] <= 1'b1; end cpll_cal_state[CHECK_X114_STATUS]: begin if (status_store) cpll_cal_state[MODIFY_PROGDIV] <= 1'b1; else cpll_cal_state[READ_PROGDIV_CFG] <= 1'b1; end cpll_cal_state[READ_PROGDIV_CFG]: begin rd <= 1'b1; if (drp_done) begin rd <= 1'b0; progdiv_cfg_store <= {1'b1,dout[14:0]}; cpll_cal_state[SAVE_PROGDIV_CFG] <= 1'b1; end else begin cpll_cal_state[READ_PROGDIV_CFG] <= 1'b1; end end cpll_cal_state[SAVE_PROGDIV_CFG]: begin wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[MODIFY_PROGDIV] <= 1'b1; end else begin cpll_cal_state[SAVE_PROGDIV_CFG] <= 1'b1; end di_msk <= progdiv_cfg_store; end cpll_cal_state[MODIFY_PROGDIV]: begin wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[MODIFY_RXOUTCLK_SEL] <= 1'b1; end else begin cpll_cal_state[MODIFY_PROGDIV] <= 1'b1; wait_ctr <= 25'd0; end di_msk<= MOD_PROGDIV_CFG; end cpll_cal_state[MODIFY_RXOUTCLK_SEL]: begin cpll_cal_state[ASSERT_RXCDRHOLD] <= 1'b1; end cpll_cal_state[ASSERT_RXCDRHOLD]: begin rxcdrhold_int <= 1'b1; cpll_cal_state[ASSERT_CPLLRESET] <= 1'b1; end cpll_cal_state[ASSERT_CPLLRESET]: begin cpllreset_int <= 1'b1; freq_counter_rst <= 1'b1; cpll_cal_state[DEASSERT_CPLLRESET] <= 1'b1; wait_ctr <= 25'd0; end cpll_cal_state[DEASSERT_CPLLRESET]: begin if (wait_ctr < WAIT_DEASSERT_CPLLRESET) begin wait_ctr <= wait_ctr + 1'b1; cpll_cal_state[DEASSERT_CPLLRESET] <= 1'b1; end else begin cpllreset_int <= 1'b0; cpll_cal_state[WAIT_GTCPLLLOCK] <= 1'b1; wait_ctr <= 16'd0; end end cpll_cal_state[WAIT_GTCPLLLOCK]: begin if(!gthe4_cplllock_sync) begin cpll_cal_state[WAIT_GTCPLLLOCK] <= 1'b1; end else begin cpll_cal_state[ASSERT_GTRXRESET] <= 1'b1; end end cpll_cal_state[ASSERT_GTRXRESET]: begin if (wait_ctr < WAIT_WIDTH_PROGDIVRESET) begin wait_ctr <= wait_ctr + 1'b1; gtrxreset_int <= 1'b1; cpll_cal_state[ASSERT_GTRXRESET] <= 1'b1; end else begin gtrxreset_int <= 1'b0; cpll_cal_state[WAIT_RXPMARESETDONE] <= 1'b1; wait_ctr <= 25'd0; end end cpll_cal_state[WAIT_RXPMARESETDONE]: begin if (gthe4_rxpmaresetdone_sync) begin cpll_cal_state[WAIT_RXPMARESETDONE_DEASSERT] <= 1'b1; end else begin cpll_cal_state[WAIT_RXPMARESETDONE] <= 1'b1; end end cpll_cal_state[WAIT_RXPMARESETDONE_DEASSERT]: begin if (!gthe4_rxpmaresetdone_sync) begin cpll_cal_state[WAIT_RXPMARESETDONE_2] <= 1'b1; end else begin cpll_cal_state[WAIT_RXPMARESETDONE_DEASSERT] <= 1'b1; end end cpll_cal_state[WAIT_RXPMARESETDONE_2]: begin if (gthe4_rxpmaresetdone_sync) begin cpll_cal_state[ASSERT_PROGDIVRESET] <= 1'b1; end else begin cpll_cal_state[WAIT_RXPMARESETDONE_2] <= 1'b1; end end cpll_cal_state[ASSERT_PROGDIVRESET]: begin if (wait_ctr < WAIT_ASSERT_PROGDIVRESET) begin wait_ctr <= wait_ctr + 1'b1; rxprogdivreset_int <= 1'b1; cpll_cal_state[ASSERT_PROGDIVRESET] <= 1'b1; end else begin rxprogdivreset_int <= 1'b0; cpll_cal_state[WAIT_PRGDIVRESETDONE] <= 1'b1; wait_ctr <= 25'd0; end end cpll_cal_state[WAIT_PRGDIVRESETDONE]: begin if (gthe4_rxprgdivresetdone_sync) begin cpll_cal_state[CHECK_FREQ] <= 1'b1; freq_counter_rst <= 1'b0; end else begin cpll_cal_state[WAIT_PRGDIVRESETDONE] <= 1'b1; end end cpll_cal_state[CHECK_FREQ]: begin if(freq_cnt_done) begin if ((rxoutclk_freq_cnt >= (RXOUTCLK_PERIOD_IN - CNT_TOL_IN)) & (rxoutclk_freq_cnt <= (RXOUTCLK_PERIOD_IN + CNT_TOL_IN))) begin cpll_cal_state[RESTORE_READ_X114] <= 1'b1; cal_fail_store <= 1'b0; end else begin if (repeat_ctr < REPEAT_RESET_LIMIT) begin cpll_cal_state[ASSERT_CPLLRESET] <= 1'b1; repeat_ctr <= repeat_ctr + 1'b1; end else begin cpll_cal_state[RESTORE_READ_X114] <= 1'b1; cal_fail_store <= 1'b1; end end end else cpll_cal_state[CHECK_FREQ] <= 1'b1; end cpll_cal_state[RESTORE_READ_X114]: begin rd <= 1'b1; if (drp_done) begin rd <= 1'b0; progdiv_cfg_store <= dout; cpll_cal_state[RESTORE_PROGDIV] <= 1'b1; end else begin cpll_cal_state[RESTORE_READ_X114] <= 1'b1; end end cpll_cal_state[RESTORE_PROGDIV]: begin wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[CLEAR_FLAG_x114] <= 1'b1; end else begin cpll_cal_state[RESTORE_PROGDIV] <= 1'b1; end di_msk <= progdiv_cfg_store; end cpll_cal_state[CLEAR_FLAG_x114]: begin //set [15] to 0 wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[WAIT_GTCPLLLOCK2] <= 1'b1; end else begin cpll_cal_state[CLEAR_FLAG_x114] <= 1'b1; end // clear di_msk <= 16'h0000; end cpll_cal_state[WAIT_GTCPLLLOCK2]: begin cpll_cal_state[ASSERT_PROGDIVRESET2] <= 1'b1; if(!gthe4_cplllock_sync) cal_fail_store <= 1'b1; else cal_fail_store <= cal_fail_store; end cpll_cal_state[ASSERT_PROGDIVRESET2]: begin if (wait_ctr < WAIT_WIDTH_PROGDIVRESET) begin wait_ctr <= wait_ctr + 1'b1; rxprogdivreset_int <= 1'b1; cpll_cal_state[ASSERT_PROGDIVRESET2] <= 1'b1; end else begin rxprogdivreset_int <= 1'b0; cpll_cal_state[WAIT_PRGDIVRESETDONE2] <= 1'b1; wait_ctr <= 25'd0; end end cpll_cal_state[WAIT_PRGDIVRESETDONE2]: begin if (gthe4_rxprgdivresetdone_sync) begin if (cal_fail_store) cpll_cal_state[CAL_FAIL] <= 1'b1; else cpll_cal_state[CAL_DONE] <= 1'b1; end else begin cpll_cal_state[WAIT_PRGDIVRESETDONE2] <= 1'b1; end end cpll_cal_state[CAL_FAIL]: begin cpll_cal_state[CAL_FAIL] <= 1'b1; mask_user_in <= 1'b0; end cpll_cal_state[CAL_DONE]: begin cpll_cal_state[CAL_DONE] <= 1'b1; mask_user_in <= 1'b0; end endcase end end // always block end else begin: gen_cpll_cal_gthe4_rx //pragma translate_on //CPLL CAL FSM always @(posedge CLK_IN) begin if (RESET_IN) begin cpll_cal_state <= 0; cpll_cal_state[RESET] <= 1'b1; cpllreset_int <= 1'b0; cpllpd_int <= 1'b0; rxprogdivreset_int <= 1'b0; mask_user_in <= 1'b0; wr <= 1'b0; rd <= 1'b0; rxcdrhold_int <= 1'b0; gtrxreset_int <= 1'b0; end else begin cpll_cal_state <= 0; case(1'b1) // synthesis parallel_case full_case cpll_cal_state[RESET]: begin wait_ctr <= 25'd0; repeat_ctr <= 4'd0; mask_user_in <= 1'b1; di_msk <= 16'b0000_0000_0000_0000; cpll_cal_state[READ_X114] <= 1'b1; end cpll_cal_state[READ_X114]: begin mask_user_in <= 1'b1; rd <= 1'b1; if (drp_done) begin rd <= 1'b0; status_store <= dout[15]; cpll_cal_state[CHECK_X114_STATUS] <= 1'b1; end else cpll_cal_state[READ_X114] <= 1'b1; end cpll_cal_state[CHECK_X114_STATUS]: begin if (status_store) cpll_cal_state[MODIFY_PROGDIV] <= 1'b1; else cpll_cal_state[READ_PROGDIV_CFG] <= 1'b1; end cpll_cal_state[READ_PROGDIV_CFG]: begin rd <= 1'b1; if (drp_done) begin rd <= 1'b0; progdiv_cfg_store <= {1'b1,dout[14:0]}; cpll_cal_state[SAVE_PROGDIV_CFG] <= 1'b1; end else begin cpll_cal_state[READ_PROGDIV_CFG] <= 1'b1; end end cpll_cal_state[SAVE_PROGDIV_CFG]: begin wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[MODIFY_PROGDIV] <= 1'b1; end else begin cpll_cal_state[SAVE_PROGDIV_CFG] <= 1'b1; end di_msk <= progdiv_cfg_store; end cpll_cal_state[MODIFY_PROGDIV]: begin wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[MODIFY_RXOUTCLK_SEL] <= 1'b1; end else begin cpll_cal_state[MODIFY_PROGDIV] <= 1'b1; wait_ctr <= 25'd0; end di_msk<= MOD_PROGDIV_CFG; end cpll_cal_state[MODIFY_RXOUTCLK_SEL]: begin cpll_cal_state[ASSERT_RXCDRHOLD] <= 1'b1; end cpll_cal_state[ASSERT_RXCDRHOLD]: begin rxcdrhold_int <= 1'b1; cpll_cal_state[ASSERT_CPLLPD] <= 1'b1; end cpll_cal_state[ASSERT_CPLLPD]: begin if (wait_ctr < WAIT_ASSERT_CPLLPD) begin wait_ctr <= wait_ctr + 1'b1; cpll_cal_state[ASSERT_CPLLPD] <= 1'b1; end else begin cpllpd_int <= 1'b1; cpll_cal_state[DEASSERT_CPLLPD] <= 1'b1; wait_ctr <= 25'd0; end end cpll_cal_state[DEASSERT_CPLLPD]: begin if (wait_ctr < SYNTH_WAIT_DEASSERT_CPLLRESET) begin wait_ctr <= wait_ctr + 1'b1; cpll_cal_state[DEASSERT_CPLLPD] <= 1'b1; end else begin cpllpd_int <= 1'b0; cpll_cal_state[ASSERT_CPLLRESET] <= 1'b1; wait_ctr <= 16'd0; freq_counter_rst <= 1'b1; end end cpll_cal_state[ASSERT_CPLLRESET]: begin if (wait_ctr < WAIT_ASSERT_CPLLRESET) begin wait_ctr <= wait_ctr + 1'b1; cpll_cal_state[ASSERT_CPLLRESET] <= 1'b1; end else begin cpllreset_int <= 1'b1; freq_counter_rst <= 1'b1; cpll_cal_state[DEASSERT_CPLLRESET] <= 1'b1; wait_ctr <= 25'd0; end end cpll_cal_state[DEASSERT_CPLLRESET]: begin if (wait_ctr < WAIT_DEASSERT_CPLLRESET) begin wait_ctr <= wait_ctr + 1'b1; cpll_cal_state[DEASSERT_CPLLRESET] <= 1'b1; end else begin cpllreset_int <= 1'b0; cpll_cal_state[WAIT_GTCPLLLOCK] <= 1'b1; wait_ctr <= 16'd0; end end cpll_cal_state[WAIT_GTCPLLLOCK]: begin if(wait_ctr < WAIT_CPLLLOCK) begin cpll_cal_state[WAIT_GTCPLLLOCK] <= 1'b1; wait_ctr <= wait_ctr + 1'b1; end else begin cpll_cal_state[ASSERT_GTRXRESET] <= 1'b1; wait_ctr <= 16'd0; end end cpll_cal_state[ASSERT_GTRXRESET]: begin if (wait_ctr < WAIT_WIDTH_PROGDIVRESET) begin wait_ctr <= wait_ctr + 1'b1; gtrxreset_int <= 1'b1; cpll_cal_state[ASSERT_GTRXRESET] <= 1'b1; end else begin gtrxreset_int <= 1'b0; cpll_cal_state[WAIT_RXPMARESETDONE] <= 1'b1; wait_ctr <= 25'd0; end end cpll_cal_state[WAIT_RXPMARESETDONE]: begin if (gthe4_rxpmaresetdone_sync) begin cpll_cal_state[WAIT_RXPMARESETDONE_DEASSERT] <= 1'b1; end else begin cpll_cal_state[WAIT_RXPMARESETDONE] <= 1'b1; end end cpll_cal_state[WAIT_RXPMARESETDONE_DEASSERT]: begin if (!gthe4_rxpmaresetdone_sync) begin cpll_cal_state[WAIT_RXPMARESETDONE_2] <= 1'b1; end else begin cpll_cal_state[WAIT_RXPMARESETDONE_DEASSERT] <= 1'b1; end end cpll_cal_state[WAIT_RXPMARESETDONE_2]: begin if (gthe4_rxpmaresetdone_sync) begin cpll_cal_state[ASSERT_PROGDIVRESET] <= 1'b1; end else begin cpll_cal_state[WAIT_RXPMARESETDONE_2] <= 1'b1; end end cpll_cal_state[ASSERT_PROGDIVRESET]: begin if (wait_ctr < WAIT_ASSERT_PROGDIVRESET) begin wait_ctr <= wait_ctr + 1'b1; rxprogdivreset_int <= 1'b1; cpll_cal_state[ASSERT_PROGDIVRESET] <= 1'b1; end else begin rxprogdivreset_int <= 1'b0; cpll_cal_state[WAIT_PRGDIVRESETDONE] <= 1'b1; wait_ctr <= 25'd0; end end cpll_cal_state[WAIT_PRGDIVRESETDONE]: begin if (gthe4_rxprgdivresetdone_sync) begin cpll_cal_state[CHECK_FREQ] <= 1'b1; freq_counter_rst <= 1'b0; end else begin cpll_cal_state[WAIT_PRGDIVRESETDONE] <= 1'b1; end end cpll_cal_state[CHECK_FREQ]: begin if(freq_cnt_done) begin if ((rxoutclk_freq_cnt >= (RXOUTCLK_PERIOD_IN - CNT_TOL_IN)) & (rxoutclk_freq_cnt <= (RXOUTCLK_PERIOD_IN + CNT_TOL_IN))) begin cpll_cal_state[RESTORE_READ_X114] <= 1'b1; cal_fail_store <= 1'b0; end else begin if (repeat_ctr < REPEAT_RESET_LIMIT) begin cpll_cal_state[ASSERT_CPLLPD] <= 1'b1; repeat_ctr <= repeat_ctr + 1'b1; end else begin cpll_cal_state[RESTORE_READ_X114] <= 1'b1; cal_fail_store <= 1'b1; end end end else cpll_cal_state[CHECK_FREQ] <= 1'b1; end cpll_cal_state[RESTORE_READ_X114]: begin rd <= 1'b1; if (drp_done) begin rd <= 1'b0; progdiv_cfg_store <= dout; cpll_cal_state[RESTORE_PROGDIV] <= 1'b1; end else begin cpll_cal_state[RESTORE_READ_X114] <= 1'b1; end end cpll_cal_state[RESTORE_PROGDIV]: begin wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[CLEAR_FLAG_x114] <= 1'b1; end else begin cpll_cal_state[RESTORE_PROGDIV] <= 1'b1; end di_msk <= progdiv_cfg_store; end cpll_cal_state[CLEAR_FLAG_x114]: begin //set [15] to 0 wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[WAIT_GTCPLLLOCK2] <= 1'b1; end else begin cpll_cal_state[CLEAR_FLAG_x114] <= 1'b1; end // clear di_msk <= 16'h0000; end cpll_cal_state[WAIT_GTCPLLLOCK2]: begin cpll_cal_state[ASSERT_PROGDIVRESET2] <= 1'b1; if(!gthe4_cplllock_sync) cal_fail_store <= 1'b1; else cal_fail_store <= cal_fail_store; end cpll_cal_state[ASSERT_PROGDIVRESET2]: begin if (wait_ctr < WAIT_WIDTH_PROGDIVRESET) begin wait_ctr <= wait_ctr + 1'b1; rxprogdivreset_int <= 1'b1; cpll_cal_state[ASSERT_PROGDIVRESET2] <= 1'b1; end else begin rxprogdivreset_int <= 1'b0; cpll_cal_state[WAIT_PRGDIVRESETDONE2] <= 1'b1; wait_ctr <= 25'd0; end end cpll_cal_state[WAIT_PRGDIVRESETDONE2]: begin if (gthe4_rxprgdivresetdone_sync) begin if (cal_fail_store) cpll_cal_state[CAL_FAIL] <= 1'b1; else cpll_cal_state[CAL_DONE] <= 1'b1; end else begin cpll_cal_state[WAIT_PRGDIVRESETDONE2] <= 1'b1; end end cpll_cal_state[CAL_FAIL]: begin rxcdrhold_int <= 1'b0; cpll_cal_state[CAL_FAIL] <= 1'b1; mask_user_in <= 1'b0; end cpll_cal_state[CAL_DONE]: begin rxcdrhold_int <= 1'b0; cpll_cal_state[CAL_DONE] <= 1'b1; mask_user_in <= 1'b0; end endcase end end // always block //pragma translate_off end //pragma translate_on always @(posedge CLK_IN) begin if (cpll_cal_state[RESET]) rxoutclksel_int <= 3'b0; else if (cpll_cal_state[MODIFY_RXOUTCLK_SEL]) rxoutclksel_int <= MOD_RXOUTCLK_SEL; else rxoutclksel_int <= rxoutclksel_int; end always @(posedge CLK_IN) begin if (cpll_cal_state[RESET]) begin daddr <= 10'h000; mask <= 16'b1111_1111_1111_1111; end else if (cpll_cal_state[READ_X114] | cpll_cal_state[SAVE_PROGDIV_CFG] | cpll_cal_state[RESTORE_READ_X114] | cpll_cal_state[CLEAR_FLAG_x114]) begin daddr <= ADDR_X114; end else if (cpll_cal_state[READ_PROGDIV_CFG] | cpll_cal_state[MODIFY_PROGDIV] | cpll_cal_state[RESTORE_PROGDIV]) begin daddr <= ADDR_RX_PROGDIV_CFG; end end assign drp_done = drp_state[DRP_DONE]; assign GTHE4_CHANNEL_DRPEN_OUT = den; assign GTHE4_CHANNEL_DRPWE_OUT = dwe; assign GTHE4_CHANNEL_DRPADDR_OUT = daddr; assign GTHE4_CHANNEL_DRPDI_OUT = di; assign drdy = GTHE4_CHANNEL_DRPRDY_IN; assign dout = GTHE4_CHANNEL_DRPDO_IN; always @(posedge CLK_IN) begin if (RESET_IN) begin den <= 1'b0; dwe <= 1'b0; di <= 16'h0000; drp_state <= 0; drp_state[DRP_WAIT] <= 1'b1; end else begin drp_state <= 0; case (1'b1) // synthesis parallel_case full_case drp_state[DRP_WAIT]: begin if (rd) drp_state[DRP_READ] <= 1'b1; else if (wr) drp_state[DRP_WRITE] <= 1'b1; else drp_state[DRP_WAIT] <= 1'b1; end drp_state[DRP_READ]: begin den <= 1'b1; drp_state[DRP_READ_ACK] <= 1'b1; end drp_state[DRP_READ_ACK]: begin den <= 1'b0; if (drdy == 1'b1) begin if (rd) drp_state[DRP_DONE] <= 1'b1; else drp_state[DRP_MODIFY] <= 1'b1; end else drp_state[DRP_READ_ACK] <= 1'b1; end drp_state[DRP_MODIFY]: begin drp_state[DRP_WRITE] <= 1'b1; end drp_state[DRP_WRITE]: begin den <= 1'b1; dwe <= 1'b1; di <= di_msk; drp_state[DRP_WRITE_ACK] <= 1'b1; end drp_state[DRP_WRITE_ACK]: begin den <= 1'b0; dwe <= 1'b0; if (drdy == 1'b1) drp_state[DRP_DONE] <= 1'b1; else drp_state[DRP_WRITE_ACK] <= 1'b1; end drp_state[DRP_DONE]: begin drp_state[DRP_WAIT] <= 1'b1; end endcase end end //debug logic - convert one hot state to binary genvar i,j; for (j=0; j<5; j=j+1) begin : jl wire [32-1:0] tmp_mask; for (i=0; i<32; i=i+1) begin : il assign tmp_mask[i] = i[j]; end assign cpll_cal_state_bin[j] = |(tmp_mask & cpll_cal_state); end end endgenerate endmodule //CPLL_CAL