// -----------------------------------------------------------------------------
// Copyright (c) 2011, ON Semiconductor.
// -----------------------------------------------------------------------------
// FILE NAME     : adc_dig.v
// TYPE          : RTL
// AUTHOR        : Stephanie Cambounet
// AUTHORS EMAIL : Stephanie.Cambounet@onsemi.com
// -----------------------------------------------------------------------------
// RELEASE HISTORY
// VERSION DATE        AUTHOR                DESCRIPTION
//  1.0    2011-11-28  Stephanie Cambounet   Initial version
// -----------------------------------------------------------------------------
// KEYWORDS : 
// -----------------------------------------------------------------------------
// PURPOSE : 
// -----------------------------------------------------------------------------
//-- Current mapping
//------------------------
//-- channel1 --
//-- channel2 --
//-- channel3 --
//-- channel4 --
//------------------------

module dig_adc (
//CLOCK
input             adc_clk_in,          //3Mhz
output            adc_clk_en,
input             adc_clk1_en,         //1.5Mhz
input             adc_clk2_en,         //750khz
input             adc_clk3_en,         //375khz
input   [1:0]     adc_clk_freq,
input             adc_ext_clk,
output            adc_clk,
//CORE
input             porb,               //to be connected to vcore_rdy & porb in top dig 

//I2C/OWI 
input             i2c_conv_req,       //manual or periodic
input   [1:0]     i2c_chan_sel,       //only in testmode
output            i2c_req_done,           

input             owi_VIT_req,
output            owi_VIT_req_done,
input             owi_VI_req,
output            owi_VI_req_done,
output            owi_V_conv_done,

output   [7:0]    ch1_data_out,        //V updated on I result
output   [7:0]    ch1_data_out_buff,   //V     
output   [7:0]    ch2_data_out,        //I
output   [7:0]    ch3_data_out,        //T

//ADC IP
input             adc_eoc,
input    [10:0]   adc_data_out,              // adc_data_out[10]= sign

output            adc_conv_en,
output            en_adc,                  //  connected to dig_sar_porb
output   [1:0]    adc_channel_mux_ctrl,

//TEST
input             testmode,
input             test_config_dft,
input             test_conv_start,           //external conv_en in test_config_dft
output   [10:0]   test_data_out, 
input             serial_en,
output            serial_data,
output            serial_frame, 

//SCAN
input             scan_mode,
input             scan_en
);

/// ****************************************************************************
/// Declarations
/// ****************************************************************************
// Internal Wires
wire        en_adc_start;
wire        en_adc_fsm;
wire [3:0]  channel_sel;
wire        adc_en;
wire        fsm_clk_en;
wire        ch1_conv_done;
wire        ch2_conv_done;
wire        ch3_conv_done;
wire        ch4_conv_done;
wire        serial_clk_en;
wire        adc_done;
wire        adc_clk_int;
reg         adc_clk_sel;

/// ****************************************************************************
/// Instances
/// ****************************************************************************
// -----------------------------------------------------------------------------
// ADC clocking
// -----------------------------------------------------------------------------
//assign adc_clk_en = sync_clk_en | fsm_clk_en | serial_clk_en;
assign adc_clk_en =  fsm_clk_en | serial_clk_en;

always @ (*) begin
    case ( adc_clk_freq )
    2'b00 : adc_clk_sel = adc_clk2_en;       //750khz  
    2'b01 : adc_clk_sel = adc_clk_en ;       //3Mhz          
    2'b10 : adc_clk_sel = adc_clk1_en;       //1.5Mhz        
    2'b11 : adc_clk_sel = adc_clk3_en;       //375khz       
    endcase
end

dig_cgc cgc_adc_clk   ( .clkout( adc_clk_int ), .clkin( adc_clk_in ), .en( adc_clk_sel & adc_clk_en ), .se( scan_en ) );

assign adc_clk = ( !scan_mode && test_config_dft ) ? adc_ext_clk : adc_clk_int;

assign en_adc = en_adc_start | en_adc_fsm;

// -----------------------------------------------------------------------------
// ADC start up
// -----------------------------------------------------------------------------
dig_adc_start_timer I_dig_adc_start_timer (
   .clk                 (adc_clk_in),
   .clk_2p66us_en       (adc_clk3_en),
   .porb                (porb),
   .i2c_conv_req        (i2c_conv_req),  
   .owi_VIT_req         (owi_VIT_req), 
   .owi_VI_req          (owi_VI_req),       
   .test_config_dft     (test_config_dft),
//   .testmode            (testmode),
   
   .en_adc              (en_adc_start),
   .i2c_conv_req_dly    (i2c_conv_req_dly), 
   .owi_VIT_req_dly     (owi_VIT_req_dly), 
   .owi_VI_req_dly      (owi_VI_req_dly)
);      

// -----------------------------------------------------------------------------
// request management
// -----------------------------------------------------------------------------
dig_adc_req I_dig_adc_req (
  .adc_clk                (adc_clk),                                 
  .rstb                    (porb),                                         
  .adc_done                (adc_done),                      
  .i2c_conv_req            (i2c_conv_req_dly),
  .i2c_ch_sel              (i2c_chan_sel),
  .owi_VIT_req             (owi_VIT_req_dly),
  .owi_VI_req              (owi_VI_req_dly),
  .ch_conv_done            ({ch4_conv_done,ch3_conv_done,ch2_conv_done,ch1_conv_done}),                                                               
  .testmode                (testmode),
  .fsm_clk_en              (fsm_clk_en),                       
//  .sync_clk_en             (sync_clk_en),
  .adc_en                  (adc_en),
  .channel_sel             (channel_sel),                    
  .i2c_req_done            (i2c_req_done),
  .owi_VIT_req_done        (owi_VIT_req_done),
  .owi_VI_req_done         (owi_VI_req_done),
  .owi_V_conv_done         (owi_V_conv_done),
  .adc_ref_en              (en_adc_fsm)
);                                                          

///assign fsm_req_done = fsm_req_ch2_done;


// -----------------------------------------------------------------------------
// conversion sequencing
// -----------------------------------------------------------------------------
dig_adc_conv_fsm I_dig_adc_conv_fsm (
   .adc_clk                (adc_clk),
   .rstb                   (porb),
   .en                     (adc_en),                     
   .eoc                    (adc_eoc),
   .channel_sel            (channel_sel),
   .test_config_dft        (test_config_dft),
   .test_conv_start        (test_conv_start),
   .conv_en                (adc_conv_en),
   .channel_mux_ctrl       (adc_channel_mux_ctrl),
   .adc_done               (adc_done),
   .ch1_conv_done          (ch1_conv_done),
   .ch2_conv_done          (ch2_conv_done),
   .ch3_conv_done          (ch3_conv_done),
   .ch4_conv_done          (ch4_conv_done)                   
);

// -----------------------------------------------------------------------------
//  result rams 
// -----------------------------------------------------------------------------
dig_adc_result I_dig_adc_result (
   .adc_clk                ( adc_clk ),
//   .rstb                   ( reg_rstb ),
   .rstb                   ( porb ),
   .ch1_conv_done          ( ch1_conv_done ),
   .ch2_conv_done          ( ch2_conv_done ),
   .ch3_conv_done          ( ch3_conv_done ),
   .ch4_conv_done          ( ch4_conv_done ),     
   .write_data             ( adc_data_out ),  
   .tb_force_clk_en        ( scan_mode ),  
   .testmode               ( testmode ),
   .scan_en                ( scan_en ),
   
   .ch1_data_out           ( ch1_data_out ),
   .ch1_data_out_buff      ( ch1_data_out_buff ),
   .ch2_data_out           ( ch2_data_out ),
   .ch3_data_out           ( ch3_data_out ),
   .test_data_out          ( test_data_out )  
);

// -----------------------------------------------------------------------------
// test serializer 
// -----------------------------------------------------------------------------
dig_adc_serializer # (
   .SERBITS          ( 11 ),
   .CNTWIDTH         ( 4 )
) I_dig_adc_serializer (
   .serdata             (serial_data),      
   .frame               (serial_frame),        
   .serial_clk_en       (serial_clk_en),      
   .serial_clk          (adc_clk),  
   .rst_b               (porb),       
   .adc_eoc             (adc_eoc),     
   .serializer_en       (serial_en),        
   .adc_data            (test_data_out)   // intead of adc_data_out for synchro issue
);   

endmodule
