//------------------------------------------------------------------------------ // (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_5_gtye4_cpll_cal_tx # ( parameter C_SIM_CPLL_CAL_BYPASS = 1'b1, parameter SIM_RESET_SPEEDUP = "TRUE", parameter C_FREERUN_FREQUENCY = 100, parameter REVISION = 2, parameter C_PCIE_ENABLE = "FALSE", parameter C_PCIE_CORECLK_FREQ = 250 )( // control signals input wire [17:0] TXOUTCLK_PERIOD_IN, input wire [15:0] WAIT_DEASSERT_CPLLPD_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 [1:0] USER_TXPLLCLKSEL, input wire USER_TXPROGDIVRESET_IN, output reg USER_TXPRGDIVRESETDONE_OUT, input wire [2:0] USER_TXOUTCLKSEL_IN, input wire USER_TXOUTCLK_BUFG_CE_IN, input wire USER_TXOUTCLK_BUFG_CLR_IN, output reg USER_CPLLLOCK_OUT, // 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 GTYE4_TXOUTCLK_IN, input wire GTYE4_CPLLLOCK_IN, output wire GTYE4_CPLLRESET_OUT, output wire GTYE4_CPLLPD_OUT, output reg GTYE4_TXPROGDIVRESET_OUT, output reg [2:0] GTYE4_TXOUTCLKSEL_OUT, input wire GTYE4_TXPRGDIVRESETDONE_IN, output wire [9:0] GTYE4_CHANNEL_DRPADDR_OUT, output wire [15:0] GTYE4_CHANNEL_DRPDI_OUT, output wire GTYE4_CHANNEL_DRPEN_OUT, output wire GTYE4_CHANNEL_DRPWE_OUT, input wire GTYE4_CHANNEL_DRPRDY_IN, input wire [15:0] GTYE4_CHANNEL_DRPDO_IN, output wire DONE ); //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_X0E1 = 1; localparam CHECK_X0E1_STATUS = 2; localparam READ_PROGCLK_SEL = 3; localparam SAVE_PROGCLK_SEL = 4; localparam READ_X079 = 5; localparam CHECK_X079_STATUS = 6; localparam READ_PROGDIV_CFG = 7; localparam SAVE_PROGDIV_CFG = 8; localparam READ_X0E1_BEFORE_PROGCLK_SEL_MOD = 9; localparam MODIFY_PROGCLK_SEL = 10; localparam MODIFY_PROGDIV = 11; localparam MODIFY_TXOUTCLK_SEL = 12; localparam ASSERT_CPLLPD = 13; localparam DEASSERT_CPLLPD = 14; localparam ASSERT_CPLLRESET = 15; localparam DEASSERT_CPLLRESET = 16; localparam WAIT_GTCPLLLOCK = 17; localparam ASSERT_PROGDIVRESET = 18; localparam WAIT_PRGDIVRESETDONE = 19; localparam CHECK_FREQ = 20; localparam RESTORE_READ_X0E1 = 21; localparam RESTORE_READ_X079 = 22; localparam RESTORE_PROGDIV = 23; localparam RESTORE_PROGCLK_SEL = 24; localparam CLEAR_FLAG_x0E1 = 25; localparam CLEAR_FLAG_x079 = 26; localparam WAIT_GTCPLLLOCK2 = 27; localparam ASSERT_PROGDIVRESET2 = 28; localparam WAIT_PRGDIVRESETDONE2= 29; localparam CAL_FAIL = 30; localparam CAL_DONE = 31; 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] progclk_sel_store = 16'd0; reg [15:0] progdiv_cfg_store = 16'd0; reg fboost_store = 1'b0; reg mask_user_in = 1'b0; reg cpllreset_int = 1'b0; reg cpllpd_int = 1'b0; reg txprogdivreset_int = 1'b0; reg [2:0] txoutclksel_int = 3'b000; reg cal_fail_store = 1'b0; reg [15:0] x0e1_store = 16'd0; 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] 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 [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 [1:0] MOD_PROGCLK_SEL = 2'b10; localparam [15:0] MOD_PROGDIV_CFG = 16'hE062; //divider 20 localparam [2:0] MOD_TXOUTCLK_SEL = 3'b101; localparam [9:0] ADDR_TX_PROGCLK_SEL = 10'h00C; localparam [9:0] ADDR_TX_PROGDIV_CFG = 10'h057; //GTY /GTH addresses are different (003E in GTH; 0057 in GTY) localparam [9:0] ADDR_X0E1 = 10'h0E1; localparam [9:0] ADDR_X079 = 10'h079; // Drive TXOUTCLK with BUFG_GT-buffered source clock, divider = 1 wire txoutclkmon; //assign txoutclkmon = GTYE4_TXOUTCLK_IN; BUFG_GT bufg_gt_txoutclkmon_inst ( .CE (USER_TXOUTCLK_BUFG_CE_IN), .CEMASK (1'b1), .CLR (USER_TXOUTCLK_BUFG_CLR_IN), .CLRMASK (1'b1), .DIV (3'b000), .I (GTYE4_TXOUTCLK_IN), .O (txoutclkmon) ); wire gtye4_cplllock_sync; gtwizard_ultrascale_v1_7_5_bit_synchronizer bit_synchronizer_cplllock_inst ( .clk_in (CLK_IN), .i_in (GTYE4_CPLLLOCK_IN), .o_out (gtye4_cplllock_sync) ); wire user_txprogdivreset_sync; gtwizard_ultrascale_v1_7_5_bit_synchronizer bit_synchronizer_txprogdivreset_inst ( .clk_in (CLK_IN), .i_in (USER_TXPROGDIVRESET_IN), .o_out (user_txprogdivreset_sync) ); wire gtye4_txprgdivresetdone_sync; gtwizard_ultrascale_v1_7_5_bit_synchronizer bit_synchronizer_txprgdivresetdone_inst ( .clk_in (CLK_IN), .i_in (GTYE4_TXPRGDIVRESETDONE_IN), .o_out (gtye4_txprgdivresetdone_sync) ); wire [2:0] user_txoutclksel_sync; gtwizard_ultrascale_v1_7_5_bit_synchronizer bit_synchronizer_txoutclksel_inst0 ( .clk_in (CLK_IN), .i_in (USER_TXOUTCLKSEL_IN[0]), .o_out (user_txoutclksel_sync[0]) ); gtwizard_ultrascale_v1_7_5_bit_synchronizer bit_synchronizer_txoutclksel_inst1 ( .clk_in (CLK_IN), .i_in (USER_TXOUTCLKSEL_IN[1]), .o_out (user_txoutclksel_sync[1]) ); gtwizard_ultrascale_v1_7_5_bit_synchronizer bit_synchronizer_txoutclksel_inst2 ( .clk_in (CLK_IN), .i_in (USER_TXOUTCLKSEL_IN[2]), .o_out (user_txoutclksel_sync[2]) ); assign GTYE4_CPLLRESET_OUT = cpllreset_int; assign GTYE4_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 <= gtye4_cplllock_sync; end generate if (C_PCIE_ENABLE) begin : pcie_txoutclksel always @(*) begin GTYE4_TXOUTCLKSEL_OUT <= mask_user_in ? txoutclksel_int : USER_TXOUTCLKSEL_IN; GTYE4_TXPROGDIVRESET_OUT <= mask_user_in ? txprogdivreset_int : USER_TXPROGDIVRESET_IN; end end else begin : non_pcie_txoutclksel always @(posedge CLK_IN) begin if (mask_user_in) GTYE4_TXPROGDIVRESET_OUT <= txprogdivreset_int; else GTYE4_TXPROGDIVRESET_OUT <= user_txprogdivreset_sync; end always @(posedge CLK_IN) begin if (mask_user_in) GTYE4_TXOUTCLKSEL_OUT <= txoutclksel_int; else GTYE4_TXOUTCLKSEL_OUT <= user_txoutclksel_sync; end end endgenerate always @(posedge CLK_IN) begin if (mask_user_in) USER_TXPRGDIVRESETDONE_OUT <= 1'b0; else USER_TXPRGDIVRESETDONE_OUT <= gtye4_txprgdivresetdone_sync; end // frequency counter for txoutclk wire [17:0] txoutclk_freq_cnt; reg freq_counter_rst = 1'b1; wire freq_cnt_done; gtwizard_ultrascale_v1_7_5_gtye4_cpll_cal_freq_counter U_TXOUTCLK_FREQ_COUNTER ( .freq_cnt_o(txoutclk_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(txoutclkmon) ); //Debug signals assign DEBUG_OUT = {cpllreset_int,cpllpd_int,gtye4_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 = txoutclk_freq_cnt; assign DONE = cpll_cal_state[CAL_DONE] | cpll_cal_state[RESET]; //pragma translate_off generate if (C_SIM_CPLL_CAL_BYPASS == 1'b1) begin: gen_sim_cpll_cal_bypass_gtye4 //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; txprogdivreset_int <= 1'b0; mask_user_in <= 1'b0; wr <= 1'b0; rd <= 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_X0E1] <= 1'b1; end cpll_cal_state[READ_X0E1]: begin mask_user_in <= 1'b1; rd <= 1'b1; if (drp_done) begin rd <= 1'b0; status_store <= dout[15]; cpll_cal_state[CHECK_X0E1_STATUS] <= 1'b1; end else cpll_cal_state[READ_X0E1] <= 1'b1; end cpll_cal_state[CHECK_X0E1_STATUS]: begin if (status_store) cpll_cal_state[READ_X079] <= 1'b1; else cpll_cal_state[READ_PROGCLK_SEL] <= 1'b1; end cpll_cal_state[READ_PROGCLK_SEL]: begin rd <= 1'b1; if (drp_done) begin rd <= 1'b0; progclk_sel_store <= dout; cpll_cal_state[SAVE_PROGCLK_SEL] <= 1'b1; end else begin cpll_cal_state[READ_PROGCLK_SEL] <= 1'b1; end end cpll_cal_state[SAVE_PROGCLK_SEL]: begin wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[READ_X079] <= 1'b1; end else begin cpll_cal_state[SAVE_PROGCLK_SEL] <= 1'b1; end di_msk <= {1'b1,progclk_sel_store[14:0]}; end cpll_cal_state[READ_X079]: begin rd <= 1'b1; if (drp_done) begin rd <= 1'b0; status_store <= dout[15]; cpll_cal_state[CHECK_X079_STATUS] <= 1'b1; end else begin cpll_cal_state[READ_X079] <= 1'b1; end end cpll_cal_state[CHECK_X079_STATUS]: begin if (status_store) cpll_cal_state[READ_X0E1_BEFORE_PROGCLK_SEL_MOD] <= 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[READ_X0E1_BEFORE_PROGCLK_SEL_MOD] <= 1'b1; end else begin cpll_cal_state[SAVE_PROGDIV_CFG] <= 1'b1; end di_msk <= progdiv_cfg_store; end cpll_cal_state[READ_X0E1_BEFORE_PROGCLK_SEL_MOD]: begin rd <= 1'b1; if (drp_done) begin rd <= 1'b0; x0e1_store <= dout; cpll_cal_state[MODIFY_PROGCLK_SEL] <= 1'b1; end else begin cpll_cal_state[READ_X0E1_BEFORE_PROGCLK_SEL_MOD] <= 1'b1; end end cpll_cal_state[MODIFY_PROGCLK_SEL]: begin wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[MODIFY_PROGDIV] <= 1'b1; end else begin cpll_cal_state[MODIFY_PROGCLK_SEL] <= 1'b1; end di_msk<= {1'b0,x0e1_store[14:12],MOD_PROGCLK_SEL,x0e1_store[9:0]}; end cpll_cal_state[MODIFY_PROGDIV]: begin wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[MODIFY_TXOUTCLK_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_TXOUTCLK_SEL]: begin 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(!gtye4_cplllock_sync) begin cpll_cal_state[WAIT_GTCPLLLOCK] <= 1'b1; end else begin cpll_cal_state[RESTORE_READ_X0E1] <= 1'b1; end end cpll_cal_state[RESTORE_READ_X0E1]: begin rd <= 1'b1; if (drp_done) begin rd <= 1'b0; progclk_sel_store <= dout; cpll_cal_state[RESTORE_READ_X079] <= 1'b1; end else begin cpll_cal_state[RESTORE_READ_X0E1] <= 1'b1; end end cpll_cal_state[RESTORE_READ_X079]: 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_X079] <= 1'b1; end end cpll_cal_state[RESTORE_PROGDIV]: begin wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[RESTORE_PROGCLK_SEL] <= 1'b1; end else begin cpll_cal_state[RESTORE_PROGDIV] <= 1'b1; end di_msk <= (C_PCIE_ENABLE) ? ((USER_TXPLLCLKSEL == 2'b11)? 16'hE078 : ((C_PCIE_CORECLK_FREQ == 250) ? 16'hE060 : 16'hE078)) : progdiv_cfg_store; end cpll_cal_state[RESTORE_PROGCLK_SEL]: begin wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[CLEAR_FLAG_x0E1] <= 1'b1; end else begin cpll_cal_state[RESTORE_PROGCLK_SEL] <= 1'b1; end di_msk <= (C_PCIE_ENABLE) ? {1'b0,progclk_sel_store[14:12],2'b10,progclk_sel_store[9:0]} : {1'b0,progclk_sel_store[14:0]}; end cpll_cal_state[CLEAR_FLAG_x0E1]: begin //set [15] to 0 wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[CLEAR_FLAG_x079] <= 1'b1; end else begin cpll_cal_state[CLEAR_FLAG_x0E1] <= 1'b1; end // clear di_msk <= 16'h0000; end cpll_cal_state[CLEAR_FLAG_x079]: 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_x079] <= 1'b1; end // clear di_msk <= 16'h0000; end cpll_cal_state[WAIT_GTCPLLLOCK2]: begin cpll_cal_state[ASSERT_PROGDIVRESET2] <= 1'b1; if(!gtye4_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; txprogdivreset_int <= 1'b1; cpll_cal_state[ASSERT_PROGDIVRESET2] <= 1'b1; end else begin txprogdivreset_int <= 1'b0; cpll_cal_state[WAIT_PRGDIVRESETDONE2] <= 1'b1; wait_ctr <= 25'd0; end end cpll_cal_state[WAIT_PRGDIVRESETDONE2]: begin if (gtye4_txprgdivresetdone_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_gtye4 //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; txprogdivreset_int <= 1'b0; mask_user_in <= 1'b0; wr <= 1'b0; rd <= 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_X0E1] <= 1'b1; end cpll_cal_state[READ_X0E1]: begin mask_user_in <= 1'b1; rd <= 1'b1; if (drp_done) begin rd <= 1'b0; status_store <= dout[15]; cpll_cal_state[CHECK_X0E1_STATUS] <= 1'b1; end else cpll_cal_state[READ_X0E1] <= 1'b1; end cpll_cal_state[CHECK_X0E1_STATUS]: begin if (status_store) cpll_cal_state[READ_X079] <= 1'b1; else cpll_cal_state[READ_PROGCLK_SEL] <= 1'b1; end cpll_cal_state[READ_PROGCLK_SEL]: begin rd <= 1'b1; if (drp_done) begin rd <= 1'b0; progclk_sel_store <= dout; cpll_cal_state[SAVE_PROGCLK_SEL] <= 1'b1; end else begin cpll_cal_state[READ_PROGCLK_SEL] <= 1'b1; end end cpll_cal_state[SAVE_PROGCLK_SEL]: begin wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[READ_X079] <= 1'b1; end else begin cpll_cal_state[SAVE_PROGCLK_SEL] <= 1'b1; end di_msk <= {1'b1,progclk_sel_store[14:0]}; end cpll_cal_state[READ_X079]: begin rd <= 1'b1; if (drp_done) begin rd <= 1'b0; status_store <= dout[15]; cpll_cal_state[CHECK_X079_STATUS] <= 1'b1; end else begin cpll_cal_state[READ_X079] <= 1'b1; end end cpll_cal_state[CHECK_X079_STATUS]: begin if (status_store) cpll_cal_state[READ_X0E1_BEFORE_PROGCLK_SEL_MOD] <= 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[READ_X0E1_BEFORE_PROGCLK_SEL_MOD] <= 1'b1; end else begin cpll_cal_state[SAVE_PROGDIV_CFG] <= 1'b1; end di_msk <= progdiv_cfg_store; end cpll_cal_state[READ_X0E1_BEFORE_PROGCLK_SEL_MOD]: begin rd <= 1'b1; if (drp_done) begin rd <= 1'b0; x0e1_store <= dout; cpll_cal_state[MODIFY_PROGCLK_SEL] <= 1'b1; end else begin cpll_cal_state[READ_X0E1_BEFORE_PROGCLK_SEL_MOD] <= 1'b1; end end cpll_cal_state[MODIFY_PROGCLK_SEL]: begin wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[MODIFY_PROGDIV] <= 1'b1; end else begin cpll_cal_state[MODIFY_PROGCLK_SEL] <= 1'b1; end di_msk<= {1'b0,x0e1_store[14:12],MOD_PROGCLK_SEL,x0e1_store[9:0]}; end cpll_cal_state[MODIFY_PROGDIV]: begin wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[MODIFY_TXOUTCLK_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_TXOUTCLK_SEL]: begin 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_PROGDIVRESET] <= 1'b1; wait_ctr <= 16'd0; end end cpll_cal_state[ASSERT_PROGDIVRESET]: begin if (wait_ctr < WAIT_WIDTH_PROGDIVRESET) begin wait_ctr <= wait_ctr + 1'b1; txprogdivreset_int <= 1'b1; cpll_cal_state[ASSERT_PROGDIVRESET] <= 1'b1; end else begin txprogdivreset_int <= 1'b0; cpll_cal_state[WAIT_PRGDIVRESETDONE] <= 1'b1; wait_ctr <= 25'd0; end end cpll_cal_state[WAIT_PRGDIVRESETDONE]: begin if (gtye4_txprgdivresetdone_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 ((txoutclk_freq_cnt >= (TXOUTCLK_PERIOD_IN - CNT_TOL_IN)) & (txoutclk_freq_cnt <= (TXOUTCLK_PERIOD_IN + CNT_TOL_IN))) begin cpll_cal_state[RESTORE_READ_X0E1] <= 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_X0E1] <= 1'b1; cal_fail_store <= 1'b1; end end end else cpll_cal_state[CHECK_FREQ] <= 1'b1; end cpll_cal_state[RESTORE_READ_X0E1]: begin rd <= 1'b1; if (drp_done) begin rd <= 1'b0; progclk_sel_store <= dout; cpll_cal_state[RESTORE_READ_X079] <= 1'b1; end else begin cpll_cal_state[RESTORE_READ_X0E1] <= 1'b1; end end cpll_cal_state[RESTORE_READ_X079]: 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_X079] <= 1'b1; end end cpll_cal_state[RESTORE_PROGDIV]: begin wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[RESTORE_PROGCLK_SEL] <= 1'b1; end else begin cpll_cal_state[RESTORE_PROGDIV] <= 1'b1; end di_msk <= (C_PCIE_ENABLE) ? ((USER_TXPLLCLKSEL == 2'b11)? 16'hE078 : ((C_PCIE_CORECLK_FREQ == 250) ? 16'hE060 : 16'hE078)) : progdiv_cfg_store; end cpll_cal_state[RESTORE_PROGCLK_SEL]: begin wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[CLEAR_FLAG_x0E1] <= 1'b1; end else begin cpll_cal_state[RESTORE_PROGCLK_SEL] <= 1'b1; end di_msk <= (C_PCIE_ENABLE) ? {1'b0,progclk_sel_store[14:12],2'b10,progclk_sel_store[9:0]} : {1'b0,progclk_sel_store[14:0]}; end cpll_cal_state[CLEAR_FLAG_x0E1]: begin //set [15] to 0 wr <= 1'b1; if (drp_done) begin wr <= 1'b0; cpll_cal_state[CLEAR_FLAG_x079] <= 1'b1; end else begin cpll_cal_state[CLEAR_FLAG_x0E1] <= 1'b1; end // clear di_msk <= 16'h0000; end cpll_cal_state[CLEAR_FLAG_x079]: 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_x079] <= 1'b1; end // clear di_msk <= 16'h0000; end cpll_cal_state[WAIT_GTCPLLLOCK2]: begin cpll_cal_state[ASSERT_PROGDIVRESET2] <= 1'b1; if(!gtye4_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; txprogdivreset_int <= 1'b1; cpll_cal_state[ASSERT_PROGDIVRESET2] <= 1'b1; end else begin txprogdivreset_int <= 1'b0; cpll_cal_state[WAIT_PRGDIVRESETDONE2] <= 1'b1; wait_ctr <= 25'd0; end end cpll_cal_state[WAIT_PRGDIVRESETDONE2]: begin if (gtye4_txprgdivresetdone_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 //pragma translate_off end endgenerate //pragma translate_on always @(posedge CLK_IN) begin if (cpll_cal_state[RESET]) txoutclksel_int <= 3'b0; else if (cpll_cal_state[MODIFY_TXOUTCLK_SEL]) txoutclksel_int <= MOD_TXOUTCLK_SEL; 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_X0E1] | cpll_cal_state[SAVE_PROGCLK_SEL] | cpll_cal_state[RESTORE_READ_X0E1] | cpll_cal_state[CLEAR_FLAG_x0E1] | cpll_cal_state[READ_X0E1_BEFORE_PROGCLK_SEL_MOD]) begin daddr <= ADDR_X0E1; end else if (cpll_cal_state[READ_X079] | cpll_cal_state[SAVE_PROGDIV_CFG] | cpll_cal_state[RESTORE_READ_X079] | cpll_cal_state[CLEAR_FLAG_x079]) begin daddr <= ADDR_X079; end else if (cpll_cal_state[READ_PROGCLK_SEL] | cpll_cal_state[MODIFY_PROGCLK_SEL] | cpll_cal_state[RESTORE_PROGCLK_SEL]) begin daddr <= ADDR_TX_PROGCLK_SEL; end else if (cpll_cal_state[READ_PROGDIV_CFG] | cpll_cal_state[MODIFY_PROGDIV] | cpll_cal_state[RESTORE_PROGDIV]) begin daddr <= ADDR_TX_PROGDIV_CFG; end end assign drp_done = drp_state[DRP_DONE]; assign GTYE4_CHANNEL_DRPEN_OUT = den; assign GTYE4_CHANNEL_DRPWE_OUT = dwe; assign GTYE4_CHANNEL_DRPADDR_OUT = daddr; assign GTYE4_CHANNEL_DRPDI_OUT = di; assign drdy = GTYE4_CHANNEL_DRPRDY_IN; assign dout = GTYE4_CHANNEL_DRPDO_IN; always @(posedge CLK_IN or posedge RESET_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; generate 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 endgenerate endmodule //CPLL_CAL