//
// LpGBT controls
//
// v1.0 jb/march/2019
//
//
//***************************************************************************
//
//  LpGBT_cntrl   [0] link reset pulse
//                [1] LpGBT power control (0 - power off, 1 - power on)
//              [3:2] Downlink EC field
//              [5:4] Downlink IC field
//              [7:6] Downlink_skipCycle
//
//                [8] lpgbt_rstb
//                [9] lpgbt_pordis
//               [10] lpgbt_mod0
//               [11] lpgbt_mod1
//               [12] lpgbt_mod2
//               [13] lpgbt_mod3
//               [14] lpgbt_stateovrd
//               [15] lpgbt_lockmode
//               [16] lpgbt_sc_i2c
//
//            [23:17] reserved
//
//            [55:24] Downlink user data
//
//***************************************************************************
//

		  
module LpGBT_control
 (  
  //module state machine inputs
  input clk,
  input rst,
  input op_start,
  input wire[55:0] LpGBT_cntrl,
		  
  //link reset 
  output reg link_reset_pulse,
			 
  //Ec & Ic data fields
  output reg[ 1:0] downlinkEcData,
  output reg[ 1:0] downlinkIcData, 
			 
  //downlink user data       
  output reg[31:0] downlinkUserData,            
			 
  //Test signals
  output reg[1:0] downlink_skipCycle,
			 
  //slow control signals
  output lpgbt_rstb,
  output lpgbt_pordis,
  output lpgbt_mod0,
  output lpgbt_mod1,
  output lpgbt_mod2,
  output lpgbt_mod3,
  output lpgbt_stateovrd,
  output lpgbt_lockmode,
  output lpgbt_sc_i2c,
 
  //power control 
  output reg lpgbt_power_up
 );
		


//variables			
reg        op_starts, op_start_reg, rst_reg, rst_flg; 
reg        op_sc;
//main body
always @(posedge clk)	
 begin	
//operation starts
        op_start_reg <= op_start;
        op_starts    <= ~op_start_reg & op_start;
		  op_sc        <= op_starts;
//reset flag
        rst_reg <= rst;
        rst_flg <= ~rst_reg & rst;
 end
 

//link reset 
reg [100:0]pulse_length;
always @(posedge clk )
begin
  if   (rst_flg)             link_reset_pulse <= 1'b0;
  else if(op_starts | op_sc) link_reset_pulse <= LpGBT_cntrl [0];
  else if(pulse_length[100]) link_reset_pulse <= 1'b0;
  
  if   (op_starts | op_sc) pulse_length <= 101'b0;
  else                     pulse_length <= {pulse_length[99:0], 1'b1};
  
end
 

// 
//Downlink data and fields
//
always @(posedge clk or posedge rst_flg)	
begin	
 if (rst_flg)
  begin
   lpgbt_power_up   <= 1'b0;
   downlinkEcData   <= 2'b00;
   downlinkIcData   <= 2'b00;
   downlinkUserData <= 32'h00000000;
  end
 else if (op_starts) 
  begin
   lpgbt_power_up   <= LpGBT_cntrl[1];
   downlinkEcData   <= LpGBT_cntrl[ 3: 2];
   downlinkIcData   <= LpGBT_cntrl[ 5: 4];
   downlinkUserData <= LpGBT_cntrl[55:24];
  end
end



//test signals 
always @(posedge clk )
begin
  if   (op_starts ) downlink_skipCycle <= LpGBT_cntrl [7:6];
  else              downlink_skipCycle <= 1'b0;
end


//slow control signals
reg [9:0] scb;
always @ (posedge clk or posedge rst_flg)
begin	
 if      (rst_flg)   scb <= 9'b000000001;
 else if (op_starts) scb <= LpGBT_cntrl [16:8];
end

 assign lpgbt_rstb      = scb[0];
 assign lpgbt_pordis    = scb[1];
 assign lpgbt_mod0      = scb[2];
 assign lpgbt_mod1      = scb[3];
 assign lpgbt_mod2      = scb[4];
 assign lpgbt_mod3      = scb[5];
 assign lpgbt_stateovrd = scb[6];
 assign lpgbt_lockmode  = scb[7];
 assign lpgbt_sc_i2c    = scb[8]; 

endmodule				