///////////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------------
//
// © 2021 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.
//  File Name       : count_gen.v 
//
//  Description     : This module implements a count pattern used to drive the CorePCS 8b10b encoder

///  Targeted device : Family           Die          Package
//                    SmartFusion2     M2S090TS     484 FBGA
//  Author          : Solutions Team

//-------------------------------------------------------------------------

//******************************************************************************
//**************************** Module Declaration ******************************
//******************************************************************************
module count_gen (
  reset_n                                                 ,
  clk                                                   ,
  error_inject						,
  data_out                                              ,
  k_out
  )                                                     ;

  input reset_n                                           ;
  input clk                                             ;
  input error_inject                                    ;
  output [15:0] data_out                                ;
  output [1:0] k_out;

  reg [1:0] sm                                        ;
  reg [7:0] c;
  reg [15:0] data_out                                   ;
  reg [1:0] k_out;
  reg	     error_inject_d1			        ;
  reg	     error_inject_d2			        ;
  reg	     error_inject_d3			        ;
  reg        error_flag;
	

always @(posedge clk or negedge reset_n)
begin
	if (~reset_n)
	begin
		error_inject_d1 <= 'b0;
		error_inject_d2 <= 'b0;
		error_inject_d3 <= 'b0;
	end
	else
	begin
		error_inject_d1 <= error_inject;
		error_inject_d2 <= error_inject_d1;
		error_inject_d3 <= error_inject_d2;
	end
end




always @ (posedge clk or negedge reset_n)
begin
	if (~reset_n)
    begin
		data_out <= 16'd0;
        k_out <= 2'b00;
        sm <= 2'b00;
        error_flag<=1'b0;
        c<=8'd0;
    end
	else 
    begin
    
    if (~error_inject_d3 & error_inject_d2)
        error_flag <= 1'b1;

    case (sm)
    2'b00: // send K28.5s
    begin      
      k_out <= 2'b11;
      data_out <= {8'hbc, 8'hbc};      

      if (c==8'd5) 
      begin
        sm<=2'b01;
        c <= 8'd0;
      end
      else
        c <= c + 1;
    end	
    2'b01: // begin sending data (count pattern)
    begin
      k_out <= 2'b00;

      if (c==8'd128) 
      begin
        sm<=2'b00;
        c <= 8'd0;
      end
      else
        c <= c + 1;

      if (error_flag)
      begin
         data_out <= {8'hf, 8'hf};
         error_flag <= 1'b0;
      end
      else
        data_out <= {c,c};

    end
    default:
    begin
      sm <= 2'b00;
      c<=8'd0;
    end
    endcase
   
  end
end
     
endmodule

