//--=================================================================================================
//-- File Name                           : cxp_host_reset.v

//-- Targeted device                     : Microsemi-SoC
//-- Author                              : India Solutions Team
//--
//-- COPYRIGHT 2020 BY MICROSEMI
//-- THE INFORMATION CONTAINED IN THIS DOCUMENT IS SUBJECT TO LICENSING RESTRICTIONS FROM MICROSEMI
//-- CORP. IF YOU ARE NOT IN POSSESSION OF WRITTEN AUTHORIZATION FROM MICROSEMI FOR USE OF THIS
//-- FILE, THEN THE FILE SHOULD BE IMMEDIATELY DESTROYED AND NO BACK-UP OF THE FILE SHOULD BE MADE.
//--
//--=================================================================================================
`timescale 1ns/1ns

module cxp_host_reset (
    host_rx_clk_i           ,   // CXP host rx_clk
    grst_n_i                ,   // global async reset
    host_hsi_rx_vld_i       ,   // CXP host Transceiver valid indication
    host_hsi_rx_rdy_i       ,   // CXP host Transceiver ready indication
  
    host_rx_rst_n_o            // low-active reset sync with host_rx_clk_i
);

input               host_rx_clk_i           ;
input               grst_n_i                ;
input               host_hsi_rx_vld_i       ;
input               host_hsi_rx_rdy_i       ;

output              host_rx_rst_n_o         ;

reg                 rx_rst_n                ;

wire                host_rx_rst_n           ;
reg     [27 : 0]    after_rdy_cnt           ;

reg                 host_hsi_rx_rdy_1dly    ;
reg                 host_hsi_rx_rdy_2dly    ;
reg                 host_hsi_rx_rdy_3dly    ;
reg                 host_hsi_rx_rdy_4dly    ;


// ------------------------------------------------------------------------------
// Reset host RX logic
// ------------------------------------------------------------------------------
always @(posedge host_rx_clk_i or negedge host_rx_rst_n) begin
    if(host_rx_rst_n == 1'b0) begin
        host_hsi_rx_rdy_1dly <= 1'b0 ;
        host_hsi_rx_rdy_2dly <= 1'b0 ;
        host_hsi_rx_rdy_3dly <= 1'b0 ;
        host_hsi_rx_rdy_4dly <= 1'b0 ;
        rx_rst_n             <= 1'b0 ;
    end
    else begin
        host_hsi_rx_rdy_1dly <= host_hsi_rx_rdy_i & host_hsi_rx_vld_i;
        host_hsi_rx_rdy_2dly <= host_hsi_rx_rdy_1dly ;
        host_hsi_rx_rdy_3dly <= host_hsi_rx_rdy_2dly ;
        host_hsi_rx_rdy_4dly <= host_hsi_rx_rdy_3dly ;
        if (host_hsi_rx_rdy_4dly == 0)
          rx_rst_n           <= 0;
        else
          rx_rst_n           <= (after_rdy_cnt == 1024) ? 1 : 0; 
    end
end

assign host_rx_rst_n_o = rx_rst_n ;

// ------------------------------------------------------------------------------
// Counting for the time of Transceiver is ready
// ------------------------------------------------------------------------------
always @(posedge host_rx_clk_i or negedge host_rx_rst_n) begin
    if(host_rx_rst_n == 1'b0)
        after_rdy_cnt <= 28'd0 ;
    else if(host_hsi_rx_rdy_4dly==1'b1 && after_rdy_cnt == 1024)
        after_rdy_cnt <= 1024 ;
    else if(host_hsi_rx_rdy_4dly==1'b1)
        after_rdy_cnt <= after_rdy_cnt + 1'b1 ;
    else
        after_rdy_cnt <= 0 ;
end
// ------------------------------------------------------------------------------
// Reset sync logic
// ------------------------------------------------------------------------------
dual_reg_sync u_host_rx_rstn_sync(
    .clk_i     ( host_rx_clk_i      ),
    .rst_n_i   ( grst_n_i           ),
    .din_i     ( 1'b1               ),
    .dout_o    ( host_rx_rst_n      )             
);
endmodule
