`timescale 1ns/10ps

module cjpat_chk(

	//--- data/control output ---
	cjpat_chk_data_8b,
	cjpat_chk_ctl,

	//--- misc control ---
	rclk,
	sys_reset_z, 
	error,
	errorcnt,
	clear_error_n
          );      

//new stuff for programability

output   error;
output   [7:0] errorcnt;

input    clear_error_n;


//--- data/control output ---
input	[7:0]	cjpat_chk_data_8b;
input		cjpat_chk_ctl;

//--- misc control ---
input		rclk;
input		sys_reset_z;	//system reset
//------------ end of I/O list --------------------------------------

//------------------------------------------------------------------------
// Parameters
//------------------------------------------------------------------------
parameter [8:0] RAMCOUNT = 9'd384;




//--------------------------------------------------------------------
// error count logic
//--------------------------------------------------------------------
reg     clear_error_n_1, clear_error_n_2, clear_error_n_3, clearerror;
wire clearoneerror ;
assign clearoneerror = (~clear_error_n_2) & clear_error_n_3;


always @(posedge rclk or negedge sys_reset_z) 
    if (~sys_reset_z) 
	begin
	  clear_error_n_1 <= #1 1'b1;
	  clear_error_n_2 <= #1 1'b1;
	  clear_error_n_3 <= #1 1'b1;
	  clearerror <= #1 1'b0;
  	end //if
    else 
	begin 
	clear_error_n_1 <= clear_error_n;
	clear_error_n_2 <= clear_error_n_1;
	clear_error_n_3 <= clear_error_n_2;
	clearerror <= #1 clearoneerror;
	end



//--------------------------------------------------------------------
// data generation logic
//--------------------------------------------------------------------

//register inputs
reg	[7:0]	cjpat_indata_reg0;
reg		cjpat_inctl_reg0;
reg	[7:0]	cjpat_indata_reg1;
reg		cjpat_inctl_reg1;
reg	[7:0]	cjpat_indata_reg2;
reg		cjpat_inctl_reg2;
reg	[7:0]	cjpat_indata_reg3;
reg		cjpat_inctl_reg3;
reg	[7:0]	cjpat_indata_reg4;
reg		cjpat_inctl_reg4;





always @(posedge rclk or negedge sys_reset_z) 
    if (~sys_reset_z) 
    	begin
	  cjpat_indata_reg0 <= #1 0;
	  cjpat_inctl_reg0 <= #1 0;
	  cjpat_indata_reg1 <= #1 0;
	  cjpat_inctl_reg1 <= #1 0;
	  cjpat_indata_reg2 <= #1 0;
	  cjpat_inctl_reg2 <= #1 0;
	  cjpat_indata_reg3 <= #1 0;
	  cjpat_inctl_reg3 <= #1 0;
	  cjpat_indata_reg4 <= #1 0;
	  cjpat_inctl_reg4 <= #1 0;
	  
	end

    else
    	begin
 	  cjpat_indata_reg0 <= #1 cjpat_chk_data_8b;
	  cjpat_inctl_reg0 <= #1 cjpat_chk_ctl;   
 	  cjpat_indata_reg1 <= #1 cjpat_indata_reg0;
	  cjpat_inctl_reg1 <= #1 cjpat_inctl_reg0;   
 	  cjpat_indata_reg2 <= #1 cjpat_indata_reg1;
	  cjpat_inctl_reg2 <= #1 cjpat_inctl_reg1;   
 	  cjpat_indata_reg3 <= #1 cjpat_indata_reg2;
	  cjpat_inctl_reg3 <= #1 cjpat_inctl_reg2;
 	  cjpat_indata_reg4 <= #1 cjpat_indata_reg3;
	  cjpat_inctl_reg4 <= #1 cjpat_inctl_reg3;
	end
	
	   
	
//--- increment data counters ---


reg     [8:0]	address;
wire     [9:0]	romdata;



ROM512X10 CJPATRAMRX 
	(.Address(address), 
	 .OutClock(rclk), 
	 .OutClockEn(1'b1), 
	 .Reset(1'b0), 
	 .Q(romdata)
	 );
	 
always @(posedge rclk or negedge sys_reset_z) 
    if (~sys_reset_z) 
	  address <= #1 0;

    else
    	begin
    	//detect a start of packet
    	if  ( (cjpat_indata_reg1[7:0] == 8'hFB) && ( cjpat_inctl_reg1 == 1'h1) )
    		address <= #1 0;
    			
	else if (address ==  RAMCOUNT -1 )
    		address <= #1 0;
    	else
    		address <= #1 address +1;
	end

//data check logic	
reg error_int, error;
	 
reg datacomp ;
reg ctlcomp ;	 
	 
always @(posedge rclk or negedge sys_reset_z) 
    if (~sys_reset_z) 
	begin
	datacomp <= #1 0;
	ctlcomp <= #1 0;
	error_int <= #1 0;
	error <= #1 0;
	end
    else
    	begin

    	datacomp <= #1 ( cjpat_indata_reg3[7:0] == romdata[7:0]);
    	ctlcomp <= #1 ( cjpat_inctl_reg3 == romdata[8]);
    	//detect an error
    	if (datacomp && ctlcomp)
    		error_int <= #1 0;
    	else
    		error_int <= #1 1;
	if (clearerror)
		error <= #1 0;
	else if (error_int)    
		error <= #1 error_int;
    	end

 


reg  [7:0] errorcnt_int, errorcnt;

always @(posedge rclk or negedge sys_reset_z) 
    if (~sys_reset_z) 
    	begin
	errorcnt_int<= #1 0;
	errorcnt <= #1 0;
	end
    else 
	begin 
	if (clearerror)
		errorcnt_int <= #1 0;
	else if (error_int)
		if (errorcnt_int != 8'hFF) 
			errorcnt_int <= #1  errorcnt_int + 1;	
	errorcnt <= #1 errorcnt_int;	
	end


endmodule
