//
// module controls the AD9508 clock chip on the COLUTA tester board
// and Bunch crossing signal generation
//
// v1.0 jb/august/2018
//
//
//***************************************************************************
//
//  AD9508 control register definition:
//
//  AD9508_cntrl   [0] RSTB  signal enable
//  AD9508_cntrl   [1] SYNCB signal enable
//  AD9508_cntrl [4:2] RSTB  signal duration
//  AD9508_cntrl [7:5] SYNCB signal duration
//
//  AD9508_cntrl    [8] BCRST enable
//  AD9508_cntrl    [9] BCR_aux enable
//  AD9508_cntrl[21:10] BCRST period
//  AD9508_cntrl[23]    ALFE_CP40_EN
//
//  RSTB, SYNCB operations are very sensitive,
//  generate only one signal at the time !!!
//
//***************************************************************************
//

module AD9508
    (  
          //module state machine inputs
          input clk,
          input rst,
          input op_start,
          input wire[23:0] AD9508_cntrl,
		  
		  
          //AD9508 control signals
          output reg RSTB,
          output reg SYNCB,
			 
          //ALFE CP40 clock enable
          output reg ALFE_CP40_EN,
		  
          //Bunch crossing signal 
          output reg BCR_AUX,
          output reg BC_RST

    );
		


//variables			
reg        op_starts, op_start_reg, rst_reg, rst_flg, op_in_progress;
reg  [2:0] SYNCB_dur, RSTB_dur; 
reg [11:0] BC_RST_period, BC_RST_cnt;

//main body
always @(posedge clk)	
 begin	
//operation starts
        op_start_reg <= op_start;
        op_starts    <= ~op_start_reg & op_start;
//reset flag
        rst_reg <= rst;
        rst_flg <= ~rst_reg & rst;
 end
 
 always @(posedge clk)	
 begin
       if (rst_flg)        
		  begin
		  
		    SYNCB_dur      <= 3'b000;
			 RSTB_dur       <= 3'b000;
			 op_in_progress <= 1'b0; 
			 ALFE_CP40_EN   <= 0;
			 
		  end
       else 
		  if (op_starts) 
		   begin
			
		    RSTB_dur       <= AD9508_cntrl [4:2];
			 SYNCB_dur      <= AD9508_cntrl [7:5];
			 op_in_progress <= 1'b1;
			 ALFE_CP40_EN   <= AD9508_cntrl [23];			 
			 
		   end
		 else if (op_in_progress & (RSTB_dur !=3'b000) & AD9508_cntrl[0]) RSTB_dur  <= RSTB_dur  - 3'b001;
		 else if (op_in_progress & (SYNCB_dur!=3'b000) & AD9508_cntrl[1]) SYNCB_dur <= SYNCB_dur - 3'b001;	
		 else if (op_in_progress       & 
		         (
					 ((RSTB_dur ==3'b000) & AD9508_cntrl[0]) | 
					 ((SYNCB_dur==3'b000) & AD9508_cntrl[1])  
					 )                                       )          op_in_progress <= 1'b0; 
		 
 end


//AD9508 output signals
always @(posedge clk or posedge rst_flg)	
begin	
 if (rst_flg)
  begin
   RSTB  <= 1'b1;
   SYNCB <= 1'b1;
  end
 else
  begin
   RSTB  <= ~(op_in_progress & AD9508_cntrl[0] & (RSTB_dur !=3'b000));
   SYNCB <= ~(op_in_progress & AD9508_cntrl[1] & (SYNCB_dur!=3'b000));
  end
 end

 
 
// 
//Bunch crossing signal runs continuosly 
//
always @(posedge clk or posedge rst_flg)	
begin	
 if (rst_flg)        BC_RST_period  <= 12'b000000000000; 
 else if (op_starts) BC_RST_period  <= AD9508_cntrl [21:10];
end


//BC_RST counter 
always @(posedge clk )
begin
  if      (op_starts)                       BC_RST_cnt <= 12'h007;
  else if (BC_RST_cnt==12'h000)              BC_RST_cnt <= BC_RST_period;  
  else if (AD9508_cntrl[8]|AD9508_cntrl[9] )BC_RST_cnt <= BC_RST_cnt - 12'b000000000001;
end

//BC_RST,  BCR_AUX

always @(posedge clk)
begin
  if (AD9508_cntrl[8] & (BC_RST_cnt==12'b000000000000))
   begin
     BC_RST <= 1'b1;
   end
  else	
   begin
     BC_RST <= 1'b0;
  end
end 

always @(posedge clk)
begin
  if (AD9508_cntrl[9] & (BC_RST_cnt==12'b000000000000))
   begin
     BCR_AUX <= 1'b1;
   end
  else	
   begin
     BCR_AUX <= 1'b0;
  end
end 
 
endmodule				