/*------------------------------------------------------------------------------
© [2025] Microchip Technology Inc. and its subsidiaries
Subject to your compliance with the terms and conditions of the license 
agreement accompanying this software, you may use this Microchip software and 
any derivatives exclusively with Microchip products. You are responsible for 
complying with third party license terms applicable to your use of third party 
software (including open source software) that may accompany this Microchip 
software. SOFTWARE IS AS IS. NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR 
STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES OF 
NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. IN NO 
EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL 
OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED 
TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE 
POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY 
LAW, MICROCHIP’S TOTAL LIABILITY ON ALL CLAIMS RELATED TO THE SOFTWARE WILL 
NOT EXCEED AMOUNT OF FEES, IF ANY, YOU PAID DIRECTLY TO MICROCHIP FOR THIS 
SOFTWARE
------------------------------------------------------------------------------*/

/*******************************************************************************
**    File Name       : pckt_generator_checker.v
**    Description     : This modules interacts with MAC. Ethernet Frames are 
						transmitted onto the 10GMAC and loopback frames are 
**						captured
**    Targeted device : Microchip FPGAs
/******************************************************************************/

module pckt_generator_checker(

//system clock
input wire SYSCLK_IN,

//system reset
input wire SYSRST_N_IN,

//APB slve 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, 

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

input wire INTERRUPT_IN,
 
  //inputs
input wire  PKT_TX_FIFO_READY_IN,
input wire  PKT_RX_VAL_IN, 
input wire  PKT_RX_SOP_IN, 
input wire [2:0] PKT_RX_MOD_IN, 
input wire  PKT_RX_ERR_IN, 
input wire  [7:0] PKT_RX_ERR_TYPE, 
input wire  PKT_RX_EOP_IN,
input wire [63:0] PKT_RX_DATA_IN, 
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, 
output reg   PKT_TX_SOP_OUT, 
output reg [2:0] PKT_TX_MOD_OUT, 
output reg   PKT_TX_EOP_OUT,
output reg [63:0] PKT_TX_DATA_OUT, 
output reg   PKT_RX_READY_OUT
  );


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
