//-------------------------------------------------------------------
//                                                                 
//-------------------------------------------------------------------------
//© 2024 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       : pattern_gen
// Created     : June-2017
// Description : This module generates counter pattern generator to transmitter  
//               
// Hierarchy   : PF_64b66b_TX_RX
//               -- pattern_generator        <-- This module   
//-------------------------------------------------------------------
`timescale 1ns/1ps

module pattern_gen    (
	dataout,  // Output of the counter
	sos, hdr, //64b66b related status signals
	tx_clk_stable, //64b66b related status signals
	lane_status_lock, //64b66b related status signals
    generate_err, //Signal to inject error using UART interface
 	clk,  // clock input
 	nreset       // reset input
	)/* synthesis syn_preserve=1 */;

 //----------STATE parameter declaration---------

parameter [2:0] STATE_0 = 3'b000;
parameter [2:0] STATE_1 = 3'b001;
parameter [2:0] STATE_2 = 3'b010;
parameter [2:0] STATE_3 = 3'b011;
parameter [2:0] STATE_4 = 3'b100;

 //----------Output Ports--------------
 output [63:0] dataout;
 output reg sos;
 output reg [3:0] hdr;
 //------------Input Ports-------------- 
 input clk, nreset, tx_clk_stable, lane_status_lock; 
 input generate_err;   

 //------------Internal Variables--------
 reg lane_status_lock_d1, lane_status_lock_d2;

 reg [31:0] cycle;
 reg [2:0] sm;
 reg [31:0] data_init0 /* synthesis syn_preserve=1 */;
 reg [31:0] data_init1;

 reg enable_data;
 reg [63:0] dataout_t;

 reg [31:0] cnt32;
 
reg generate_err_d1, generate_err_d2;

//Registering UART control input

always@(posedge clk,negedge nreset)
 begin
  if (nreset == 1'b0)
  begin
  generate_err_d1 <= 1'b0;
  generate_err_d2 <= 1'b0;
  end
  else
  begin
  generate_err_d1 <= generate_err;
  generate_err_d2 <= generate_err_d1;
  end
end

//-------------Code Starts Here-------

//******************************************************************************
//*************************** Registering lane_status_lock *********************
//******************************************************************************

  always @(posedge clk or negedge nreset)
  begin
	  if (!nreset)
        begin
		  lane_status_lock_d1 <= 1'b0;
		  lane_status_lock_d2 <= 1'b0;
        end
	  else
        begin
		  lane_status_lock_d1 <= lane_status_lock;
		  lane_status_lock_d2 <= lane_status_lock_d1;
        end
  end


//***************************************************************************
//*************************** Main STATE machine ****************************
//***************************************************************************

always @ (posedge clk or negedge nreset)
begin
	if (!nreset)
        begin
            data_init0 <= 32'h00000000;
            data_init1 <= 32'h78000000;
            sos <= 1'b1;
            sm <= 3'b000;
            cycle <= 32'b0;
            hdr <= 4'b0010;
            enable_data <= 1'b0;
        end
	else 
    begin


        case (sm)
        STATE_0: // Check if transmitter clock is stable and proceed
        begin  
          if(tx_clk_stable == 1'b1) 
                begin    
                sm <= STATE_1;
                end
            else
                begin
                sm <= STATE_0;
                end
        end	

        STATE_1: // Check for Lane status lock signal
        begin      
                if(lane_status_lock_d2 == 1'b1) 
                    begin
                    sos <= 1'b1;
                    cycle <= 32'd0;
                    hdr <= 4'b0010;
                    data_init0 <= 32'h00000000;
                    data_init1 <= 32'h00000000;
                    enable_data <= 1'b1;
                    sm <= STATE_3;
                    end
                else
                    begin
                    sos <= 1'b1;
                    cycle <= 32'd0;
                    hdr <= 4'b0010;
                    data_init0 <= 32'h00000000;
                    data_init1 <= 32'h78000000; //Send start of sequence
                    sm <= STATE_2;
                    end
        end	

        STATE_2: // Send sequence boundary for every 32 clock beats
        begin      
          if(cycle == 32'd31) 
                begin
                sos <= 1'b0;
                cycle <= 32'd0;
                sm <= STATE_1;
                end
            else
                begin
                sos <= 1'b0;
                cycle <= cycle + 1'b1;
                sm <= STATE_2;
                end
        end	


        STATE_3: //Send sequence boundary for 32 clock beats and one dead cycle
        begin      
          if(cycle == 32'd31) 
                begin
                sos <= 1'b0;
                cycle <= 32'd0;
                hdr <= 4'b0001;
                sm <= STATE_4;
                enable_data <= 1'b1;
                end
            else if(cycle == 32'd30)
                begin
                sos <= 1'b0;
                hdr <= 4'b0001;
                cycle <= cycle + 1'b1;
                sm <= STATE_3;
                enable_data <= 1'b0;
                end
            else if(cycle <= 32'd29)
                begin
                sos <= 1'b0;
                hdr <= 4'b0001;
                cycle <= cycle + 1'b1;
                sm <= STATE_3;
                enable_data <= 1'b1;
                end
        end	

        STATE_4: // Sending data until lane_status_lock signal is present
        begin      
                sos <= 1'b1;
                hdr <= 4'b0001;
                cycle <= 32'd0;
                sm <= STATE_3;
                enable_data <= 1'b1;
        end	



        default:
        begin
            sos <= 1'b0;
            sm <= STATE_0;
            cycle <= 32'b0;
            hdr <= 4'b0010;
            enable_data <= 1'b0;
        end

        endcase
    end
end

//***************************************************************************
/****************************************************************************/
//count32 generator

   always @(posedge clk or negedge nreset)
     if (!nreset)
        begin
            cnt32 <= 32'h00000000;
        end
     else       
        begin
            if  (enable_data == 1'b1) 
              begin 
                cnt32 <= cnt32 + 1'b1;
              end                
        end

/****************************************************************************/
/****************************************************************************/
//dataout generator
   always @(posedge clk or negedge nreset)
    begin
     if (!nreset)
        begin
            dataout_t  <= 64'h7800000000000000;
        end
     else
        begin
            if (enable_data == 1'b0)
                begin
                    dataout_t  <= {data_init1,data_init0};
                end
            else
                begin
                    dataout_t  <= {cnt32,cnt32};
                end
        end
    end
//**************************************************************************

assign dataout = (generate_err_d2 == 1'b0) ? dataout_t : 64'hFFFFFFFFFFFFFFFF;


endmodule 
