//************************************************************************
//
// module controls PA&SHAPER chip
// v1.0 jb/march/2018
//
//
//***************************************************************************
//
//  PA&SHAPER control register definition:
//
//  PA_cntrl_cntrl[0] resetB flag
//                [1] select flag
//            [277:2] Serial data  field (2 serial chips)
//
//***************************************************************************
//

module PA_SHAPER
    (  
      //module state machine inputs
      input     clk,
      input     rst,
      input     op_start,
      input wire[279:0] PA_cntrl,
		  
      //serial slow control signals
      output reg rstb_sr,
      output     select,
      input      srout_sr,			 
      output reg clk_sr,
      output     srin_sr,
		
		output reg [277:0] PA_cntrl_reg
    );
		
//parameter chain_length=12'd276; //138+138

//variables			
reg          op_started, rst_reg, rst_flg; 
reg   [11:0] bit_count;
reg          op_starts;
reg          shift_in_progress;
reg    [5:0] clk_div;
reg          clk1M;

//
//main body
//

reg le_phase_start, rst_pulse;
always @(posedge clk)	
 begin	
//reset flag
        rst_reg      <= rst;
        rst_flg      <= ~rst_reg & rst;	  
 end

 
//reset flag generated before the data
reg [180:0]pulse_length;
always @(posedge clk)
begin
 if     (op_start)          rstb_sr = PA_cntrl[0];
 else if(pulse_length[140]) rstb_sr = 1'b1;
 
 if (op_start) pulse_length <= 181'b0;
 else          pulse_length <= {pulse_length[179:0], 1'b1};
end 
 

//shift operation in progress
always @(posedge clk or posedge rst_flg)
begin

//pulse phase 
  if (rst_flg) le_phase_start <= 1'b0;
  else         le_phase_start <= ~pulse_length[144] & pulse_length[143];
  
  if      (rst_flg)           op_started <= 1'b0;
  else if (le_phase_start )   op_started <= 1'b1; //if rstb_sr, no clocks
  else if (op_starts)         op_started <= 1'b0;


  if      (rst_flg)            shift_in_progress <= 1'b0;
  else if (op_started )        shift_in_progress <= 1'b1;
  else if (bit_count==12'h000) shift_in_progress <= 1'b0;
end 

//serial clock divider
always @(posedge clk or negedge shift_in_progress)
begin
  if (!shift_in_progress)       clk_div <= 6'b000000;
  else
   begin
    if   ( clk_div==6'b101000)  clk_div <= 6'b000000;
    else                        clk_div <= clk_div + 6'b000001;
   end
end

//serial clock
always @(posedge clk)
begin
 if(clk_div<=6'b010100) clk_sr <= 1'b0;
 else                   clk_sr <= 1'b1;
 
 if(clk_div<=6'b010100) clk1M <= 1'b0;
 else                   clk1M <= 1'b1;
end


//1MHz clock domain
always @(posedge clk1M or posedge op_started)
begin
  if      (op_started)  op_starts <= 1'b1;
  else if (op_starts)   op_starts <= 1'b0;
end


//select flag
assign  select  = PA_cntrl [1];


//bit counter
always @(negedge clk1M or posedge op_starts)
begin
  if      (op_starts)         bit_count <= (select==1'b1) ? {12'd276} : {12'd50};
  else if (shift_in_progress) bit_count <= bit_count - 12'h001;
end

//serial register
always @(negedge clk1M or posedge op_starts)
begin
  if     (op_starts)        PA_cntrl_reg <= {PA_cntrl[277:2]};
  else if(shift_in_progress)PA_cntrl_reg <= {PA_cntrl_reg[274:0], srout_sr};
end


assign srin_sr = (select==1'b1) ? PA_cntrl_reg[275] : PA_cntrl_reg[49];

endmodule				