///////////////////////////////////////////////////////////////////////////////								
//-------------------------------------------------------------------------								
// Copyright 2023 Microchip Technology Inc. and its subsidiaries								
// All rights reserved.								
// ANY USE OR REDISTRIBUTION IN PART OR IN WHOLE MUST BE HANDLED IN								
// ACCORDANCE WITH THE MICROCHIP LICENSE AGREEMENT AND MUST BE APPROVED								
// IN ADVANCE IN WRITING.								
//								
//-----------------------------------------------------------------------------								
// Title : <pckt_generator_checker>								
// Created : <June 2020>								
// Description : This modules interacts with MAC. Ethernet Frames are 
//				 transmitted onto the 10GMAC and loopback frames are captured				
// Hierarchy : pckt_generator_checker															
//-----------------------------------------------------------------------------		


module pckt_generator_checker(

//system clock
input wire SYSCLK_IN,

//system reset
input wire SYSRST_N_IN,

//APB slave inputs
input wire PCLK_IN,
input wire PRESET_N_IN, 
input wire PWRITE_IN,  
input wire PENABLE_IN,
input wire PSEL_IN,   
input wire [31:0] PADDR_IN, 
input wire [31:0] PWDATA_IN, 

//APB slave Outputs
output reg [31:0] PRDATA_OUT,
output wire  PREADY_OUT,

input wire INTERRUPT_IN,
 
//inputs
input wire  PKT_TX_FIFO_READY_IN, //TX Ready signal from MAC interface
input wire  PKT_RX_VAL_IN, // RX enable from MAC for handshake
input wire  PKT_RX_SOP_IN, //MAC RX SOP
input wire [2:0] PKT_RX_MOD_IN, 
input wire  PKT_RX_ERR_IN, //Packet Error signal indication from MAC
input wire  [7:0] PKT_RX_ERR_TYPE, //Various error type signals from MAC
input wire  PKT_RX_EOP_IN, //MAC RX EOP
input wire [63:0] PKT_RX_DATA_IN, //Data from MAC 
input wire [3:0] ERR_TYPE_IN, 
input wire [23:0] RX_STAT_IN,
input wire RX_STAT_VLD_IN,
  
  // OUTPUTS
output reg   PKT_TX_VAL_OUT, //Data valid signal
output reg   PKT_TX_SOP_OUT, // SOP signal to MAC
output reg [2:0] PKT_TX_MOD_OUT, 
output reg   PKT_TX_EOP_OUT, // EOP signal to MAC
output reg [63:0] PKT_TX_DATA_OUT, // TX data interface 
output reg   PKT_RX_READY_OUT //packet receive enable signal
  );


parameter [2:0] IDLE_TX = 3'b000;
parameter [2:0] SOP_TX = 3'b001;
parameter [2:0] LEN_TX = 3'b010;
parameter [2:0] DATA_TX = 3'b011;
parameter [2:0] EOP_TX	= 3'b100;
parameter [2:0] WAIT_TX = 3'b101;

parameter [2:0] IDLE_RCV = 3'b000;
parameter [2:0] DATA_RCV = 3'b001;

parameter ADDR_START 		 = 8'h00;
parameter ADDR_STOP 		 = 8'h04;
parameter ADDR_DONE 		 = 8'h08;
parameter ADDR_NUMPKTS 	     = 8'h0C;
parameter ADDR_PKTLENGTH 	 = 8'h10;
parameter ADDR_MACSA0 		 = 8'h14;
parameter ADDR_MACSA1 		 = 8'h18;
parameter ADDR_MACDA0 		 = 8'h1C;
parameter ADDR_MACDA1 		 = 8'h20;
parameter ADDR_IDLE_CNT 	 = 8'h24;
parameter ADDR_TXPKTCNT_MSB  = 8'h28;
parameter ADDR_TXPKTCNT_LSB  = 8'h2C;
parameter ADDR_RANDOMLENGTH  = 8'h30;
parameter ADDR_RANDOMPAYLOAD = 8'h34;
parameter ADDR_RNDSEED0 	 = 8'h38;
parameter ADDR_RNDSEED1 	 = 8'h3C;
parameter ADDR_RNDSEED2 	 = 8'h40;

parameter ADDR_MON_CTRL 	 = 8'h50;
parameter ADDR_GOOD_PACKETS_MSB  = 8'h54;
parameter ADDR_GOOD_PACKETS_LSB  = 8'h58;
parameter ADDR_ERROR_PACKETS_MSB = 8'h5C;
parameter ADDR_ERROR_PACKETS_LSB = 8'h60;
parameter ADDR_RCV_BYTE_CNT_MSB = 8'h64;
parameter ADDR_RCV_BYTE_CNT_LSB = 8'h68;

//reg [10:0] pckt_length_reg;
//wire [10:0] pckt_length_tx;
reg [15:0] pckt_length_reg; // Jumbo packet support - 9K bytes
wire [15:0] pckt_length_tx;
reg [31:0] no_of_Packets_reg;

reg start;
reg [2:0]start_q;
wire start_p;
reg stop;
reg [1:0]stop_q;
reg op_done;
reg [1:0] op_done_q;
reg clear_op_done;
reg [2:0] clear_op_done_q;
wire clear_op_done_p;
reg clear_mon_counters;
reg [2:0] clear_mon_counters_q;
wire mon_init;

wire [3:0] byte_en;
reg [2:0] pckt_gen_fsm_state;
reg [2:0] pckt_recv_fsm_state;
reg [63:0] pckt_count;
reg [47:0] source_address;
reg [47:0] destination_address;
reg [15:0] count;
reg [15:0] wait_count;
reg [63:0] data_pattern;
wire    [7:0] DA5,DA4,DA3,DA2,DA1,DA0; 
wire    [7:0] SA5,SA4,SA3,SA2,SA1,SA0;  
wire [15:0] payload_length;
reg [15:0] idle_wait_cnt;
reg [63:0] good_pkts;
reg [63:0] bad_pkts;
reg [63:0] rcv_byte_cnt;
reg crc_checker_en;
wire crc_pass;
wire crc_done;
reg random_length;
reg [15:0] random_seed;
wire [15:0] tx_prbs;
wire prbs_load;
wire prbs_en;


reg [31:0] no_of_Packets_reg_r1;
reg [31:0] no_of_Packets_reg_r2;
reg [15:0] pckt_length_reg_r1; 
reg [15:0] pckt_length_reg_r2;

assign PREADY_OUT = 1'b1;



`define TP #1

reg    tbi_txclk_irst1;
reg    tbi_txclk_irst2;
reg    tbi_rxclk_irst1;
reg    tbi_rxclk_irst2;
wire   SYSRST_N_IN_SYNC;
// --------------------------------------------------------------------------
// -- Reset Strategy
// Because each clock can be stopped or very slow with respect to a
// possible host reset pulse the host reset occurrence must be caught in 
// the synchronizing stages.  Each reset is thus asserted 
// reset asynchronous to its clock but deasserted synchronously with the
// host reset bit. All register genreated resets are bypassed during scan 
// mode and are directly controlled from the mstrrst input.

// --------------------------------------------------------------------------
// -- TBI_TXCLK_IRST reset synchronized

always @ ( posedge SYSCLK_IN or negedge SYSRST_N_IN)
begin
  if(!SYSRST_N_IN) 
    tbi_txclk_irst1 <= 1'b0;
  else    
    tbi_txclk_irst1 <= SYSRST_N_IN;
end

always @ (posedge SYSCLK_IN or negedge SYSRST_N_IN )
begin
  if(!SYSRST_N_IN)
    tbi_txclk_irst2 <= 1'b0;
  else  
    tbi_txclk_irst2 <= tbi_txclk_irst1;
end

assign SYSRST_N_IN_SYNC = tbi_txclk_irst2;

//APB write 
always @(posedge PCLK_IN /*or negedge PRESET_N_IN*/) 
begin
	if (!PRESET_N_IN)begin
		start <= 1'b0;
		stop <= 1'b0;
		clear_op_done <= 1'b0;
		no_of_Packets_reg <= 0;
		pckt_length_reg <= 0;
		source_address[47:0] <= 48'h0; 
		destination_address[47:0] <= 48'h0;
		idle_wait_cnt <= 16'h0;
		clear_mon_counters <= 1'b0;
		crc_checker_en <= 1'b0;
		random_length <= 1'b0;
		random_seed <= 16'h5EED;
  	end	else if(PSEL_IN & PENABLE_IN & PWRITE_IN) begin
    		case(PADDR_IN[7:0])
				ADDR_START         : start <= PWDATA_IN[0];
				ADDR_STOP          : stop <= PWDATA_IN[0];
				ADDR_DONE          : clear_op_done <= PWDATA_IN[0]; // clearing status register data        @ FIC32_0 address 3000_0008
    			ADDR_NUMPKTS       : no_of_Packets_reg   <= PWDATA_IN; // latching number of packets input  (0-continuous transmission )     @ FIC32_0 address 3000_000C
//    			ADDR_PKTLENGTH     : pckt_length_reg[10:0] <= PWDATA_IN[10:0]; // latching packet length      @ FIC32_0 address 3000_0010
                ADDR_PKTLENGTH     : pckt_length_reg[15:0] <= PWDATA_IN[15:0]; // Jumbo packet support - 9K bytes// latching packet length      @ FIC32_0 address 3000_0010
				ADDR_MACSA0        : source_address[31:0] <= PWDATA_IN[31:0];
				ADDR_MACSA1        : source_address[47:32] <= PWDATA_IN[15:0];
				ADDR_MACDA0        : destination_address[31:0] <= PWDATA_IN[31:0];
				ADDR_MACDA1        : destination_address[47:32] <= PWDATA_IN[15:0];
				ADDR_IDLE_CNT      : idle_wait_cnt <= PWDATA_IN[15:0];
				ADDR_RANDOMLENGTH  : random_length <= PWDATA_IN[0];
				ADDR_RNDSEED0      : random_seed <= PWDATA_IN[15:0];
				ADDR_MON_CTRL      : begin
                                     	clear_mon_counters <= PWDATA_IN[0];
                                        crc_checker_en <= PWDATA_IN[1];
									 end
			endcase
	end
	else begin
		start <= 1'b0;
		clear_op_done <= 1'b0;
		clear_mon_counters <= 1'b0;
	end
end

//APB read 
always @(*)
begin
	if (!PRESET_N_IN)
		PRDATA_OUT <= 0;
	else if(PSEL_IN & !PWRITE_IN & PENABLE_IN) begin
    		case(PADDR_IN[7:0])
				ADDR_START         : PRDATA_OUT <= {31'b0,start};//0
				ADDR_STOP          : PRDATA_OUT <= {31'b0,stop};//4
    			ADDR_DONE          : PRDATA_OUT <= {31'b0,op_done_q[1]};//8  
    			ADDR_NUMPKTS       : PRDATA_OUT <= no_of_Packets_reg;//  c 
    			ADDR_PKTLENGTH     : PRDATA_OUT <= {16'b0,pckt_length_reg[15:0]};//10   
				ADDR_MACSA0        : PRDATA_OUT <= source_address[31:0]; //14
				ADDR_MACSA1        : PRDATA_OUT <= {16'h0,source_address[47:32]}; 
				ADDR_MACDA0        : PRDATA_OUT <= destination_address[31:0]; //1c
				ADDR_MACDA1        : PRDATA_OUT <= {16'h0,destination_address[47:32]};//20 
				ADDR_IDLE_CNT      : PRDATA_OUT <= {16'h0,idle_wait_cnt[15:0]};
				ADDR_TXPKTCNT_MSB  : PRDATA_OUT <= pckt_count[63:32];//28
				ADDR_TXPKTCNT_LSB  : PRDATA_OUT <= pckt_count[31:0];//2c
				ADDR_RANDOMLENGTH  : PRDATA_OUT <= {31'b0,random_length};//30
				ADDR_RNDSEED0      : PRDATA_OUT <= {16'h0000,random_seed[15:0]};//
				ADDR_MON_CTRL      : PRDATA_OUT <= {30'b0,crc_checker_en,clear_mon_counters};//34
				ADDR_GOOD_PACKETS_MSB  : PRDATA_OUT <= good_pkts[63:32];
				ADDR_GOOD_PACKETS_LSB  : PRDATA_OUT <= good_pkts[31:0];
				ADDR_ERROR_PACKETS_MSB : PRDATA_OUT <= bad_pkts[63:32];
				ADDR_ERROR_PACKETS_LSB : PRDATA_OUT <= bad_pkts[31:0];
				ADDR_RCV_BYTE_CNT_MSB : PRDATA_OUT <= rcv_byte_cnt[63:32];
				ADDR_RCV_BYTE_CNT_LSB : PRDATA_OUT <= rcv_byte_cnt[31:0];
				default : PRDATA_OUT <= 0;
			endcase
	end	else begin
		PRDATA_OUT <= 0;
	end
end

always @(posedge PCLK_IN /*or negedge PRESET_N_IN*/) 
begin
	if (!PRESET_N_IN)begin
		op_done_q[1:0] <= 2'b00;
  	end	else begin
		op_done_q[1:0] <= {op_done_q[0],op_done};
	end
end


assign {DA5,DA4,DA3,DA2,DA1,DA0} = destination_address[47:0];
assign {SA5,SA4,SA3,SA2,SA1,SA0} = source_address[47:0];
//assign payload_length[15:0] = (random_length == 1'b1)? {5'b00000,((tx_prbs[10:0] % 16'h05AF)+ 8'h2e)}:{5'b00000,(pckt_length_reg[10:0] - 11'b00000001110)};
//assign pckt_length_tx = (random_length == 1'b1)? ((tx_prbs[10:0] % 16'h05AF) + 8'h3c):pckt_length_reg;
//assign payload_length[15:0] = {5'b00000,(pckt_length_reg[10:0] - 11'b00000001110)};
assign payload_length[15:0] = pckt_length_reg_r2[15:0];// Jumbo packet support - 9K bytes
assign pckt_length_tx = pckt_length_reg_r2;
always @ (posedge SYSCLK_IN /*or negedge SYSRST_N_IN*/)
begin
	if (!SYSRST_N_IN_SYNC)
	begin
 		start_q[2:0] <= 3'b000;
		clear_mon_counters_q[2:0] <= 3'b000;
		clear_op_done_q[2:0] <= 3'b000;
		stop_q[1:0] <= 2'b00;
    end else begin
		start_q[2:0] <= {start_q[1:0],start};
		clear_mon_counters_q[2:0] <= {clear_mon_counters_q[1:0],clear_mon_counters};
		clear_op_done_q[2:0] <= {clear_op_done_q[1:0] ,clear_op_done};
		stop_q[1:0] <= {stop_q[0],stop};
	end
end


assign start_p = {start_q[1] & !start_q[2]};
assign mon_init ={clear_mon_counters_q[1]&!clear_mon_counters_q[2]};
assign clear_op_done_p = {clear_op_done_q[1]&!clear_op_done_q[2]};


//assign prbs_load = (pckt_gen_fsm_state == IDLE_TX)? 1'b1:1'b0;
//assign prbs_en = (pckt_gen_fsm_state == SOP_TX)? 1'b1:1'b0;


//lfsr_16 # (.width(16)) lfsr_16_inst (
//.clk(SYSCLK_IN), 
//.rst_n(SYSRST_N_IN),
//.set_seed(prbs_load), 
//.seed(random_seed[15:0]), 
//.enable(prbs_en),
//.rand_out(tx_prbs[15:0]) );
//Synchronization Logic
always @ (posedge SYSCLK_IN /*or negedge SYSRST_N_IN*/)
begin
  no_of_Packets_reg_r1 <= no_of_Packets_reg;
  no_of_Packets_reg_r2 <= no_of_Packets_reg_r1;
  pckt_length_reg_r1 <= pckt_length_reg;
  pckt_length_reg_r2 <= pckt_length_reg_r1;
end 


//PACKET GENERATION STATE MACHINE
always @ (posedge SYSCLK_IN /*or negedge SYSRST_N_IN*/)
begin
	if (!SYSRST_N_IN_SYNC)
	begin
		pckt_gen_fsm_state <= IDLE_TX;
		PKT_TX_VAL_OUT <=1'b0;
		PKT_TX_SOP_OUT <=1'b0;
		PKT_TX_MOD_OUT <= 3'b000;
        PKT_TX_EOP_OUT <= 1'b0;
		PKT_TX_DATA_OUT <= 64'h0;
		count <= 16'h0000;
        wait_count <= 16'h0000;
		op_done <= 1'b0;
		pckt_count <= 64'h0;
		data_pattern <= 64'h0;
	end
	else begin

	case (pckt_gen_fsm_state)
		IDLE_TX : begin
					PKT_TX_VAL_OUT <=1'b0;
					PKT_TX_SOP_OUT <=1'b0;
					PKT_TX_MOD_OUT <= 3'b000;
        			PKT_TX_EOP_OUT <= 1'b0;
					PKT_TX_DATA_OUT <= 64'h0;
			        wait_count <= 16'h0000;
					data_pattern <= 64'h0;
					if (start_p == 1'b1) begin
						pckt_gen_fsm_state <= SOP_TX;
						op_done <= 1'b0;
						pckt_count <= 64'h0;
					end
					else begin
						pckt_gen_fsm_state <= IDLE_TX;
						if (mon_init) begin
							pckt_count <= 64'h0;
						end else begin
							pckt_count <= pckt_count;
						end
						if 	(clear_op_done_p == 1'b1) begin
							op_done <= 1'b0;
                        end
					end
					count <= 16'h0000;
				end

		SOP_TX : begin
				PKT_TX_SOP_OUT <=1'b1;
				PKT_TX_MOD_OUT <= 3'b000;
        		PKT_TX_EOP_OUT <= 1'b0;
                PKT_TX_DATA_OUT <= {SA1,SA0,DA5,DA4,DA3,DA2,DA1,DA0};
                //PKT_TX_DATA_OUT <= 64'hAAAAAAAAAAAAAAAA;
				wait_count <= 16'h0000;
				data_pattern <= 64'h0;
				if (PKT_TX_FIFO_READY_IN == 1'b1) begin
					PKT_TX_VAL_OUT <=1'b1;
					pckt_gen_fsm_state <= LEN_TX;
					count <= 16'h0008;
				end else begin
					PKT_TX_VAL_OUT <=1'b0;
					count <= 16'h0000;	
					pckt_gen_fsm_state <= SOP_TX;	
				end
			   end

		LEN_TX : begin
				PKT_TX_SOP_OUT <=1'b0;
				PKT_TX_MOD_OUT <= 3'b000;
        		PKT_TX_EOP_OUT <= 1'b0;
				data_pattern <= 64'h0001020304050607;
                //data_pattern <= 64'hAAAAAAAAAAAAAAAA;
				PKT_TX_DATA_OUT <= {pckt_count[15:0],payload_length[15:0],SA5,SA4,SA3,SA2};
                //PKT_TX_DATA_OUT <= 64'hAAAAAAAAAAAAAAAA;
                wait_count <= 16'h0000;				
				if (PKT_TX_FIFO_READY_IN == 1'b1) begin
					PKT_TX_VAL_OUT <=1'b1;
					pckt_gen_fsm_state <= DATA_TX;
					count <= 16'h0010;
				end else begin
					PKT_TX_VAL_OUT <=1'b0;
					count <= count;	
					pckt_gen_fsm_state <= LEN_TX;	
				end
			   end

		DATA_TX : begin
				PKT_TX_SOP_OUT <=1'b0;
				PKT_TX_MOD_OUT <= 3'b000;
        		PKT_TX_EOP_OUT <= 1'b0;
                wait_count <= 16'h0000;
				PKT_TX_DATA_OUT <= data_pattern;
				if (PKT_TX_FIFO_READY_IN == 1'b1) begin
					PKT_TX_VAL_OUT <=1'b1;
					count <= count +16'h0008;
					data_pattern <= data_pattern + 64'h0808080808080808;
                    //data_pattern <= 64'hAAAAAAAAAAAAAAAA;
					if (count < (pckt_length_tx-16'b0000000000010000)) begin
						pckt_gen_fsm_state <= DATA_TX;
					end	else begin
						pckt_gen_fsm_state <= EOP_TX; 
					end
				end else begin
					PKT_TX_VAL_OUT <=1'b0;
					count <= count;
					data_pattern <= data_pattern;
					pckt_gen_fsm_state <= DATA_TX;	
				end
				end

		EOP_TX : begin	
				PKT_TX_SOP_OUT <=1'b0;
				PKT_TX_MOD_OUT <= (4'b1000-(pckt_length_tx % 8));
        		PKT_TX_EOP_OUT <= 1'b1;
                wait_count <=  16'h0000;
				PKT_TX_DATA_OUT <= data_pattern;
				if (PKT_TX_FIFO_READY_IN == 1'b1) begin
					PKT_TX_VAL_OUT <=1'b1;
					pckt_gen_fsm_state <= WAIT_TX;
					data_pattern <= 64'h0;
					count <= 16'h0000;
				end else begin
					PKT_TX_VAL_OUT <=1'b0;
					count <= count;
					data_pattern <= data_pattern;
					pckt_gen_fsm_state <= EOP_TX;
				end
	  		   end

		WAIT_TX : begin
					PKT_TX_VAL_OUT <=1'b0;
					PKT_TX_SOP_OUT <=1'b0;
					PKT_TX_MOD_OUT <= 3'b000;
        			PKT_TX_EOP_OUT <= 1'b0;
					data_pattern <= 64'h0;
					PKT_TX_DATA_OUT <= 64'h0;
					if (wait_count < idle_wait_cnt) begin
						pckt_gen_fsm_state <= WAIT_TX;
						wait_count <= wait_count + 16'h0001;
					end	else begin
						if (stop_q[1]) begin
							pckt_gen_fsm_state <= IDLE_TX;
							op_done <= 1'b1;
						end else begin
							if (no_of_Packets_reg_r2 == 32'h0) begin
								pckt_gen_fsm_state <= SOP_TX;
								op_done <= 1'b0;
							end else if(pckt_count < no_of_Packets_reg_r2-32'h00000001) begin
								pckt_gen_fsm_state <= SOP_TX;
								op_done <= 1'b0;
							end	else begin
								pckt_gen_fsm_state <= IDLE_TX;
								op_done <= 1'b1;
							end
						end
						pckt_count <= pckt_count + 64'h00000001;
						wait_count <= 16'h0000;
					end	
	  			end


		default : begin 
					PKT_TX_VAL_OUT <=1'b0;
					PKT_TX_SOP_OUT <=1'b0;
					PKT_TX_MOD_OUT <= 3'b000;
        			PKT_TX_EOP_OUT <= 1'b0;
					data_pattern <= 64'h0;
					PKT_TX_DATA_OUT <= 64'h0;
					pckt_gen_fsm_state <= IDLE_TX;
					count <= 16'h0000;
					op_done <= 1'b0;
					pckt_count <= 64'h0;
		            wait_count <= 16'h0000;
				  end
	endcase
	end
end

//PACKET RECEPTION STATE MACHINE
always @ (posedge SYSCLK_IN /*or negedge SYSRST_N_IN*/)
begin
	if (!SYSRST_N_IN_SYNC)
	begin
		pckt_recv_fsm_state <= IDLE_RCV;
		PKT_RX_READY_OUT <= 1'b0;
	end
	else begin
	PKT_RX_READY_OUT <= 1'b1;
	case (pckt_recv_fsm_state)
        IDLE_RCV : begin
						pckt_recv_fsm_state <= DATA_RCV;
						PKT_RX_READY_OUT <= 1'b0;
				end

		DATA_RCV : begin
					if (PKT_RX_VAL_IN == 1'b1) begin
						if (PKT_RX_SOP_IN == 1'b1) begin
							pckt_recv_fsm_state <= DATA_RCV;
							PKT_RX_READY_OUT <= 1'b1;
						end	else if (PKT_RX_EOP_IN == 1'b1) begin
							pckt_recv_fsm_state <= IDLE_RCV;
							PKT_RX_READY_OUT <= 1'b0;
						end	else begin
							pckt_recv_fsm_state <= DATA_RCV;
							PKT_RX_READY_OUT <= 1'b1;
						end
					end	else begin		
						pckt_recv_fsm_state <= DATA_RCV;
						PKT_RX_READY_OUT <= 1'b1;	
					end
					end
		default : begin 
				pckt_recv_fsm_state <= IDLE_RCV;
				PKT_RX_READY_OUT <= 1'b0;
			end
	endcase
	end
end


 // ____________________________________________
 //	packet counters
 // ____________________________________________

 always @ (posedge SYSCLK_IN /*or negedge SYSRST_N_IN*/)
   begin
      if (!SYSRST_N_IN_SYNC) 
        begin
          good_pkts <= 64'h0;
      	  bad_pkts <= 64'h0;
		  rcv_byte_cnt <= 64'h0;
        end else
        begin
            if(mon_init)
                begin
                    good_pkts <= 64'h0;
                    bad_pkts <= 64'h0;
                    rcv_byte_cnt <= 64'h0;
                end else        
                begin
			//if (!crc_checker_en) begin
                    if (PKT_RX_VAL_IN & PKT_RX_EOP_IN & !PKT_RX_ERR_IN) 
                    begin
                        good_pkts <= good_pkts + 64'h1;
                    end 
                    else if (PKT_RX_VAL_IN & PKT_RX_EOP_IN & PKT_RX_ERR_IN) 
                    begin 
                        bad_pkts <= bad_pkts + 64'h1;
                    end
                end /*else begin
				if (crc_done & crc_pass) begin
					good_pkts <= good_pkts + 64'h1;
				end else if(crc_done & !crc_pass) begin
					bad_pkts <= bad_pkts + 64'h1;
				end
			end*/
                if(PKT_RX_VAL_IN) 
                begin
                    if (!PKT_RX_EOP_IN) 
                    begin
                        rcv_byte_cnt <= rcv_byte_cnt + 64'h8;
                    end else 
                    begin
                        if (byte_en[3] == 1'b1) 
                            begin
                                rcv_byte_cnt <= rcv_byte_cnt +  64'h8;
                            end else 
                            begin
                                rcv_byte_cnt <= rcv_byte_cnt + byte_en[2:0];
                            end
                    end 		
                end
        end
   end

assign byte_en[3:0]  = 4'b1000 - PKT_RX_MOD_IN[2:0];



endmodule
