


module xcvr_lpbk (

// reset and clocks
input			reset ,
input			xcvr_refclk ,	//transciever ref clock
input			gp_clk , 	//50MHz clock

//highspeed io
input			rx_p ,
output			tx_p ,

//status - control
input			load,		//load prbs with seed and clear status
input		[19:0]	prbs_seed ,
input		[19:0]	txerror_vec ,

output reg	[19:0]	err_count , 
output			compare ,
output			rx_freqlock,
output			rx_phcomperr ,
output			pll_locked ,
output			tx_phcomperr , 
output			rx_clkout 

) ;
//end of xcvr loop back

wire 	[19:0]	rxdata, prbs_20 ;
wire 	[19:0]	rx_sdi_data ;

///////////////////////////////////////////////////////////////
// prbs data generator
parallel20_prbs15	prbs_u0 (
	.clk			( tx_clkout ) ,
	//.reset			( reset ) ,
	.prbs_seed		( prbs_seed ) ,
	.load			( reset ) ,
	//lsfr_out,
	.dataout20		( prbs_20 )
	);


reg	[19:0]	txdata ;
////////////////////////////////////////////////////////////////////
// insert data error 
reg	[19:0]	txerror_vec_r, txerror_vec_r2 ;

always @ (posedge tx_clkout ) begin
  	
  	//sync to the xcvr referenc clock
  	txerror_vec_r	<= #1 txerror_vec ;
  	txerror_vec_r2	<= #1 txerror_vec_r ;

  	txdata		<= #1 prbs_20 ^ txerror_vec_r2 ;
end




xcvr	xcvr_u1 (
	.cal_blk_clk 			( gp_clk ),
	.pll_inclk 			( xcvr_refclk ),
	.rx_analogreset 		( reset ),
	.rx_coreclk 			( rx_clkout ),
	.rx_cruclk 			( xcvr_refclk ),
	.rx_datain 			( rx_p ),
	.rx_digitalreset 		( reset ),
	.tx_coreclk			( tx_clkout ),
	.tx_datain 			( {
					txdata[0],
					txdata[1],
					txdata[2],
					txdata[3],
					txdata[4],
					txdata[5],
					txdata[6],
					txdata[7],
					txdata[8],
					txdata[9],
					txdata[10],
					txdata[11],
					txdata[12],
					txdata[13],
					txdata[14],
					txdata[15],
					txdata[16],
					txdata[17],
					txdata[18],
					txdata[19] } ),
	.tx_digitalreset 		( reset ),
	.pll_locked 			( pll_locked ),
	.rx_clkout 			( rx_clkout ),
	.rx_dataout 			( {
					rxdata[0],
					rxdata[1],
					rxdata[2],
					rxdata[3],
					rxdata[4],
					rxdata[5],
					rxdata[6],
					rxdata[7],
					rxdata[8],
					rxdata[9],
					rxdata[10],
					rxdata[11],
					rxdata[12],
					rxdata[13],
					rxdata[14],
					rxdata[15],
					rxdata[16],
					rxdata[17],
					rxdata[18],
					rxdata[19] } ),
	.rx_freqlocked 			( rx_freqlock ),
	.rx_pll_locked 			( rx_plllocked ),
	.tx_clkout 			( tx_clkout ),
	.tx_dataout 			( tx_p ),
	.debug_rx_phase_comp_fifo_error	(  ) ,
	.debug_tx_phase_comp_fifo_error (  )
	);






//////////////////////////////////////////////////////


reg	[59:0] 	holdreg ;

wire	[19:0]	prbsrx_data ;
wire		dataout ;

////////////////////////////////////////////////////////////////////
// this is used for the receive data checker
// count tc is used to reload every once in a while just in case error in
// bit stream. FYI: this is pretty dumb - eventually it would be done under uP control
// logic control noting the number of errors. 
parallel20_prbs15 prbsrx (
	.clk		( rx_clkout ) ,
	//.reset		( reset ) ,
	.prbs_seed	( holdreg[19:0] ) ,
	.load		( load ) ,
	//.load		( count_tc ) ,
	.dataout20	( prbsrx_data ) 
	) ;


//////////////////////////////////////////////////////////////
// holding register used to check the data input
always @ (posedge rx_clkout or posedge reset)
begin
  if ( reset ) begin
  	holdreg		<= #1 59'h555_5555_DEAD_BEEF ;
  end
  else  begin 
  	holdreg[59:0]	<= #1 { holdreg[39:0], rxdata[19:0] }  ;
    end
end


//////////////////////////////////////////////////////////////////
// counter to reset prbs seed to sync up to the input data stream.
/*
reg	[20:0]	count ;
reg		count_tc ;
always @ (posedge rx_clkout or posedge reset)
begin
  if (reset ) begin
  	count		<= #1 0 ;
	count_tc	<= #1 1'b0 ;
  end
  else begin 
 	
  	if ( count[20] )  begin
  		count		<= #1 0 ;
  		count_tc	<= #1 1'b1 ;
  	  end
  	else begin
  		count		<= #1 count + 1 ;
  		count_tc	<= #1 1'b0 ;
  	 end
  end
end
*/

///////////////////////////////////////////////////////
// added clocked register for timing relief. 

//wire compare ;
//assign compare = (prbsrx_data == holdreg[39:20] ) ;

reg		compare_r ;
reg		load_r, load_r2 ;

//declared up on the output signals
//reg	[19:0]	err_count ;

always @ (posedge rx_clkout or posedge reset)
begin
	if( reset ) 
	begin
		compare_r 	<= #1 1'b0 ;
		err_count	<= #1 20'b0 ;
	//else
	//	compare_r	<= #1 ( prbsrx_data == holdreg[39:20] ) ;
	end	
	
	else 
	begin
		// double register for clock domain cross
		load_r		<= #1 load ;
		load_r2		<= #1 load_r ;
		
		// use load to clear counters and comparison reg
		if ( load_r2  ) begin
			compare_r	<= #1 1'b1 ;
			err_count	<= #1 0 ;
			end
		
		//////////////////////////////////
		// disable the compare reg
		// increment the error counter
		else if ( prbsrx_data != holdreg[39:20]  ) begin
			compare_r	<= #1 1'b0 ;
			err_count	<= #1 err_count + 1 ;
			end
		else
			compare_r	<= #1 compare_r ;

	end
end



assign compare = compare_r ;
	
	
endmodule


