// xcvr_sample_tb.v

// Generated using ACDS version 16.1 203

`timescale 1 ps / 1 ps
module xcvr_sample_top (
	input wire        reset_n,
	input wire        clk_100m_clk,
	input wire        clk_625m_clk,
	output wire       xcvr_tx_serial_data,
	input wire        xcvr_rx_serial_data,
	output wire [3:0] user_led_g,
	output wire [3:0] user_led_r
	);

	wire    xcvr_sample_inst_clk_100m_bfm_clk_clk;    // xcvr_sample_inst_clk_100m_bfm:clk -> [xcvr_sample_inst:clk_100m_clk, xcvr_sample_inst_reset_n_bfm:clk]
	wire    xcvr_sample_inst_clk_625m_bfm_clk_clk;    // xcvr_sample_inst_clk_625m_bfm:clk -> xcvr_sample_inst:clk_625m_clk
	wire    xcvr_sample_inst_reset_n_bfm_reset_reset; // xcvr_sample_inst_reset_n_bfm:reset -> xcvr_sample_inst:reset_n_reset_n

//	xcvr_sample_inst_clk_100m_bfm_ip #(.CLOCK_RATE (100000000)) xcvr_sample_inst_clk_100m_bfm (
//		.clk (xcvr_sample_inst_clk_100m_bfm_clk_clk)  //  output,  width = 1, clk.clk
//	);
//
//	xcvr_sample_inst_clk_625m_bfm_ip #(.CLOCK_RATE (625000000)) xcvr_sample_inst_clk_625m_bfm (
//		.clk (xcvr_sample_inst_clk_625m_bfm_clk_clk)  //  output,  width = 1, clk.clk
//	);
//
//	xcvr_sample_inst_reset_n_bfm_ip xcvr_sample_inst_reset_n_bfm (
//		.reset (xcvr_sample_inst_reset_n_bfm_reset_reset), //  output,  width = 1, reset.reset_n
//		.clk   (xcvr_sample_inst_clk_100m_bfm_clk_clk)     //   input,  width = 1,   clk.clk
//	);


	wire       xcvr_rx_clk ;
    wire       xcvr_tx_clk ;

//    wire       xcvr_tx_serial_data ;
//    wire       xcvr_rx_serial_data ;
    wire       xcvr_rx_seriallpbken ;
    wire[31:0] xcvr_tx_parallel_data ;
    wire[3:0]  xcvr_tx_data_k ;
    wire[91:0] xcvr_tx_parallel_data_unused ;
    wire[31:0] xcvr_rx_parallel_data ;
    wire[3:0]  xcvr_rx_data_k ;
    wire[3:0]  xcvr_rx_errdetect ;
    wire[3:0]  xcvr_rx_disperr ;
    wire[3:0]  xcvr_rx_runningdisp ;
    wire[3:0]  xcvr_rx_patterndetect ;
    wire[3:0]  xcvr_rx_syncstatus ;
    wire       xcvr_rx_std_wa_patternalign ;
    wire       xcvr_reset_tx_ready ;
    wire       xcvr_reset_control_0_pll_select ;
    wire       xcvr_reset_rx_ready ;

    wire       s_rx_no_err ;
    reg [1:0]  s_xcvr_reset_rx_ready_2r ;
    wire       s_xcvr_rx_ready ;
    reg [7:0]  s_aligned_cnt ;
    reg [3:0]  s_rx_patterndetect_latched ;
    wire       s_rx_aligned_status ;
    reg [31:0] s_xcvr_rx_parallel_data_0th ;
    wire[31:0] rx_dataout_32b ;
    reg [1:0]  s_xcvr_reset_tx_ready_2r ;
    wire       s_xcvr_tx_ready ;
    reg [1:0]  s_rx_aligned_status_2r ;
    wire       s_rx_aligned_status_txclk ;
    reg [9:0]  s_cnt_10b ;
	 wire[3:0]  led_a;
	 wire[3:0]  led_b;
	
	assign xcvr_sample_inst_clk_100m_bfm_clk_clk = clk_100m_clk;
	assign xcvr_sample_inst_clk_625m_bfm_clk_clk = clk_625m_clk;
	assign xcvr_sample_inst_reset_n_bfm_reset_reset = reset_n;	
	
	assign led_a[0] = (rx_dataout_32b[ 3: 0] == 4'h0)? 1'b1 : 1'b0 ;
	assign led_a[1] = (rx_dataout_32b[ 7: 4] == 4'h0)? 1'b1 : 1'b0 ;
	assign led_a[2] = (rx_dataout_32b[11: 8] == 4'h0)? 1'b1 : 1'b0 ;
	assign led_a[3] = (rx_dataout_32b[15:12] == 4'h0)? 1'b1 : 1'b0 ;
	assign led_b[0] = (rx_dataout_32b[19:16] == 4'h0)? 1'b1 : 1'b0 ;
	assign led_b[1] = (rx_dataout_32b[23:20] == 4'h0)? 1'b1 : 1'b0 ;
	assign led_b[2] = (rx_dataout_32b[27:24] == 4'h0)? 1'b1 : 1'b0 ;
	assign led_b[3] = (rx_dataout_32b[31:28] == 4'h0)? 1'b1 : 1'b0 ;

	assign user_led_r[0] = led_a[0];
	assign user_led_r[1] = led_a[1];
	assign user_led_r[2] = led_a[2];
	assign user_led_r[3] = led_a[3];
	assign user_led_g[0] = led_b[0];
	assign user_led_g[1] = led_b[1];
	assign user_led_g[2] = led_b[2];
	assign user_led_g[3] = led_b[3];	
	
	xcvr_sample xcvr_sample_inst (
		.clk_100m_clk                                                      (xcvr_sample_inst_clk_100m_bfm_clk_clk),    //                                  clk_100m.clk
		.clk_625m_clk                                                      (xcvr_sample_inst_clk_625m_bfm_clk_clk),    //                                  clk_625m.clk
		.reset_n_reset_n                                                   (xcvr_sample_inst_reset_n_bfm_reset_reset), //                                   reset_n.reset_n
		.rx_coreclk_out_clk                                                (xcvr_rx_clk),                                         //                            rx_coreclk_out.clk
		.tx_coreclk_out_clk                                                (xcvr_tx_clk),                                         //                            tx_coreclk_out.clk
		.xcvr_native_a10_0_rx_datak_rx_datak                               (xcvr_rx_data_k),                                         //                xcvr_native_a10_0_rx_datak.rx_datak
		.xcvr_native_a10_0_rx_disperr_rx_disperr                           (xcvr_rx_disperr),                                         //              xcvr_native_a10_0_rx_disperr.rx_disperr
		.xcvr_native_a10_0_rx_errdetect_rx_errdetect                       (xcvr_rx_errdetect),                                         //            xcvr_native_a10_0_rx_errdetect.rx_errdetect
		.xcvr_native_a10_0_rx_parallel_data_rx_parallel_data               (xcvr_rx_parallel_data),                                         //        xcvr_native_a10_0_rx_parallel_data.rx_parallel_data
		.xcvr_native_a10_0_rx_patterndetect_rx_patterndetect               (xcvr_rx_patterndetect),                                         //        xcvr_native_a10_0_rx_patterndetect.rx_patterndetect
		.xcvr_native_a10_0_rx_runningdisp_rx_runningdisp                   (xcvr_rx_runningdisp),                                         //          xcvr_native_a10_0_rx_runningdisp.rx_runningdisp
		.xcvr_native_a10_0_rx_serial_data_rx_serial_data                   (xcvr_rx_serial_data),                                         //          xcvr_native_a10_0_rx_serial_data.rx_serial_data
		.xcvr_native_a10_0_rx_seriallpbken_rx_seriallpbken                 (xcvr_rx_seriallpbken),                                         //         xcvr_native_a10_0_rx_seriallpbken.rx_seriallpbken
		.xcvr_native_a10_0_rx_std_wa_patternalign_rx_std_wa_patternalign   (xcvr_rx_std_wa_patternalign),                                         //  xcvr_native_a10_0_rx_std_wa_patternalign.rx_std_wa_patternalign
		.xcvr_native_a10_0_rx_syncstatus_rx_syncstatus                     (xcvr_rx_syncstatus),                                         //           xcvr_native_a10_0_rx_syncstatus.rx_syncstatus
		.xcvr_native_a10_0_tx_datak_tx_datak                               (xcvr_tx_data_k),                                         //                xcvr_native_a10_0_tx_datak.tx_datak
		.xcvr_native_a10_0_tx_parallel_data_tx_parallel_data               (xcvr_tx_parallel_data),                                         //        xcvr_native_a10_0_tx_parallel_data.tx_parallel_data
		.xcvr_native_a10_0_tx_serial_data_tx_serial_data                   (xcvr_tx_serial_data),                                         //          xcvr_native_a10_0_tx_serial_data.tx_serial_data
		.xcvr_native_a10_0_unused_tx_parallel_data_unused_tx_parallel_data (xcvr_tx_parallel_data_unused),                                          // xcvr_native_a10_0_unused_tx_parallel_data.unused_tx_parallel_data
		.xcvr_reset_control_0_pll_select_pll_select                        (xcvr_reset_control_0_pll_select),                                         //           xcvr_reset_control_0_pll_select.pll_select
		.xcvr_reset_control_0_rx_ready_rx_ready                            (xcvr_reset_rx_ready),                                         //             xcvr_reset_control_0_rx_ready.rx_ready
		.xcvr_reset_control_0_tx_ready_tx_ready                            (xcvr_reset_tx_ready)                                          //             xcvr_reset_control_0_tx_ready.tx_ready
		);

///////////////////////////
//// loopback ////

//assign xcvr_rx_serial_data = xcvr_tx_serial_data ;

assign xcvr_tx_parallel_data_unused    = 92'd0 ;
assign xcvr_reset_control_0_pll_select = 1'b0 ;

assign xcvr_rx_seriallpbken        = 1'b0 ;
assign xcvr_rx_std_wa_patternalign = 1'b0 ;

///////////////////////////
//// alignment pattern ////

wire[31:0] s_align_pattern_32b  = 32'hbcbcbc1c;
wire[3:0]  s_align_pattern_k_4b = 4'hF;

////////////////////////////
//// rx alignment check ////

assign s_rx_no_err = (xcvr_rx_errdetect == 4'h0 && xcvr_rx_disperr == 4'h0)? 1'b1 : 1'b0 ;

always@(negedge xcvr_sample_inst_reset_n_bfm_reset_reset or posedge xcvr_rx_clk) begin
    if (~xcvr_sample_inst_reset_n_bfm_reset_reset)
        s_xcvr_reset_rx_ready_2r <= 2'h0 ;
    else
        s_xcvr_reset_rx_ready_2r <= {s_xcvr_reset_rx_ready_2r[0], xcvr_reset_rx_ready} ;
end

assign s_xcvr_rx_ready = s_xcvr_reset_rx_ready_2r[1] ;

always@(negedge s_xcvr_rx_ready or posedge xcvr_rx_clk) begin
    if (~s_xcvr_rx_ready)
        s_aligned_cnt                <= 8'h00 ;
    else begin
        if (s_rx_no_err) begin
            if (~s_rx_aligned_status)
                s_aligned_cnt <= s_aligned_cnt + 8'h01 ;
            else
                s_aligned_cnt <= s_aligned_cnt ;
        end
        else
            s_aligned_cnt <= 8'h00 ;
    end
end


always@(negedge s_xcvr_rx_ready or posedge xcvr_rx_clk) begin
    if (~s_xcvr_rx_ready)
        s_rx_patterndetect_latched <= 4'h0 ;
    else begin
        if (~s_rx_aligned_status)
            s_rx_patterndetect_latched <= xcvr_rx_patterndetect ;
        else
            s_rx_patterndetect_latched <= s_rx_patterndetect_latched ;
    end
end

assign s_rx_aligned_status = s_aligned_cnt[7] ;

always@(negedge s_xcvr_rx_ready or posedge xcvr_rx_clk) begin
    if (~s_xcvr_rx_ready)
        s_xcvr_rx_parallel_data_0th <= 32'h00000000 ;
    else
        s_xcvr_rx_parallel_data_0th <= xcvr_rx_parallel_data ;
end

assign rx_dataout_32b = (s_rx_patterndetect_latched == 4'b1110)?                               s_xcvr_rx_parallel_data_0th[31:0] :
                        (s_rx_patterndetect_latched == 4'b1101)? {xcvr_rx_parallel_data[ 7:0], s_xcvr_rx_parallel_data_0th[31:8]} :
                        (s_rx_patterndetect_latched == 4'b1011)? {xcvr_rx_parallel_data[15:0], s_xcvr_rx_parallel_data_0th[31:16]} :
                        (s_rx_patterndetect_latched == 4'b0111)? {xcvr_rx_parallel_data[23:0], s_xcvr_rx_parallel_data_0th[31:24]} :
                          32'h00000000 ;


/////////////////////////
//// tx_data_pattern ////

always@(negedge xcvr_sample_inst_reset_n_bfm_reset_reset or posedge xcvr_tx_clk) begin
    if (~xcvr_sample_inst_reset_n_bfm_reset_reset)
        s_xcvr_reset_tx_ready_2r <= 2'h0 ;
    else
        s_xcvr_reset_tx_ready_2r <= {s_xcvr_reset_tx_ready_2r[0], xcvr_reset_tx_ready} ;
end

assign s_xcvr_tx_ready = s_xcvr_reset_tx_ready_2r[1] ;


always@(negedge s_xcvr_tx_ready or posedge xcvr_tx_clk) begin
    if (~s_xcvr_tx_ready)
        s_rx_aligned_status_2r <= 2'h0 ;
    else
        s_rx_aligned_status_2r <= {s_rx_aligned_status_2r[0], s_rx_aligned_status} ;
end

assign s_rx_aligned_status_txclk = s_rx_aligned_status_2r[1] ;


always@(negedge s_xcvr_tx_ready or posedge xcvr_tx_clk) begin
    if (~s_xcvr_tx_ready)
        s_cnt_10b <= 10'h000 ;
    else begin
        if (s_rx_aligned_status_txclk)
            s_cnt_10b <= s_cnt_10b + 10'h001 ;
        else
            s_cnt_10b <= 10'h000 ;
    end
end

assign xcvr_tx_parallel_data = (~s_rx_aligned_status_txclk)? s_align_pattern_32b : {s_cnt_10b[1:0], s_cnt_10b, s_cnt_10b, s_cnt_10b} ;
assign xcvr_tx_data_k        = (~s_rx_aligned_status_txclk)? s_align_pattern_k_4b : 4'h0 ;

// -------- Added above

endmodule
