// -----------------------------------------------------------------------------
// Copyright (c) 2013, ON Semiconductor.
// -----------------------------------------------------------------------------
// FILE NAME     : dig_clk.v
// TYPE          : RTL
// AUTHOR        : Franck Da Costa
// AUTHORS EMAIL : Franck.DaCosta@onsemi.com
// -----------------------------------------------------------------------------
// RELEASE HISTORY
// VERSION DATE        AUTHOR               DESCRIPTION
//  1.0    2013-10-21  Stephanie Cambounet  Initial version
// -----------------------------------------------------------------------------
// KEYWORDS : 
// -----------------------------------------------------------------------------
// PURPOSE : 
// -----------------------------------------------------------------------------

module dig_clk (
//Inputs
input          clk_12Mhz,     // 83.3ns clock
input          vcore_rdy,     // vcore_rdy
input          scan_en,       // scan shift enable
input          tb_fast_clk,   // TB: bypass all counters

//Outputs
output         clk_166ns,     //   6    Mhz clock
output         clk_333ns,     //   3    Mhz clock
output         clk_666ns,     //   1.5  Mhz clock
output         clk_1p33us,    // 750     khz clock
output         clk_2p66us,    // 375     khz clock
output         clk_5p33us,    // 187.5   khz clock
output         clk_10p6us,    //  93.75  khz clock
output         clk_21p3us,    //  46.87  khz clock
output         clk_42p6us,    //  23.44  khz clock
output         clk_85p3us,    //  11.72  khz clock
output         clk_170p6us,   //   5.86  khz clock
output         clk_341p3us,   //   2.93  khz clock
output         clk_682p6us,   //   1.46  khz clock
output         clk_1p37ms,    // 732    hz clock
output         clk_2p73ms,    // 366    hz clock
output         clk_5p46ms,    // 183    hz clock
output         clk_10p9ms,    //  91    hz clock
output         clk_21p8ms,    //  46    hz clock
output         clk_43p7ms,    //  23    hz clock

output         clk_166ns_en,     //   6   Mhz clock
output         clk_333ns_en,     //   3   Mhz clock
output         clk_666ns_en,     // 1.5   Mhz clock
output         clk_1p33us_en,    // 750     khz clock
output         clk_2p66us_en,    // 375     khz clock
output         clk_5p33us_en,    // 187.5   khz clock
output         clk_10p6us_en,    //  93.75  khz clock
output         clk_21p3us_en,    //  46.87  khz clock
output         clk_42p6us_en,    //  23.44  khz clock
output         clk_85p3us_en,    //  11.72  khz clock
output         clk_170p6us_en,   //   5.86  khz clock
output         clk_341p3us_en,   //   2.93  khz clock
output         clk_682p6us_en,   //   1.46  khz clock
output         clk_1p37ms_en,    // 732    hz clock
output         clk_2p73ms_en,    // 366    hz clock
output         clk_5p46ms_en,    // 183    hz clock
output         clk_10p9ms_en,    //  91    hz clock
output         clk_21p8ms_en,    //  46    hz clock
output         clk_43p7ms_en     //  23    hz clock
);


/// ****************************************************************************
/// Declarations
/// ****************************************************************************
// -----------------------------------------------------------------------------
// Internal Regs
// -----------------------------------------------------------------------------
reg            clk_166ns_50_50;
reg            clk_333ns_50_50;
reg            clk_666ns_50_50;
reg            clk_1p33us_50_50;
reg            clk_2p66us_50_50;
reg            clk_5p33us_50_50;
reg            clk_10p6us_50_50;
reg            clk_21p3us_50_50;
reg            clk_42p6us_50_50;
reg            clk_85p3us_50_50;
reg            clk_170p6us_50_50;
reg            clk_341p3us_50_50;
reg            clk_682p6us_50_50;
reg            clk_1p37ms_50_50;
reg            clk_2p73ms_50_50;
reg            clk_5p46ms_50_50;
reg            clk_10p9ms_50_50;
reg            clk_21p8ms_50_50;
reg            clk_43p7ms_50_50;

/// ****************************************************************************
/// Processes
/// ****************************************************************************

/// ----------------------------------------------------------------------------
/// RIPPLE COUNTERS
/// ----------------------------------------------------------------------------
always @ (posedge clk_12Mhz or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_166ns_50_50 <= 1'b1;
   else
      clk_166ns_50_50 <= ~clk_166ns_50_50;
end

always @ (posedge clk_166ns or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_333ns_50_50 <= 1'b1;
   else
      clk_333ns_50_50 <= ~clk_333ns_50_50;
end

always @ (posedge clk_333ns or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_666ns_50_50 <= 1'b1;
   else
      clk_666ns_50_50 <= ~clk_666ns_50_50;
end

always @ (posedge clk_666ns or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_1p33us_50_50 <= 1'b1;
   else
      clk_1p33us_50_50 <= ~clk_1p33us_50_50;
end

always @ (posedge clk_1p33us or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_2p66us_50_50 <= 1'b1;
   else
      clk_2p66us_50_50 <= ~clk_2p66us_50_50;
end

always @ (posedge clk_2p66us or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_5p33us_50_50 <= 1'b1;
   else
      clk_5p33us_50_50 <= ~clk_5p33us_50_50;
end

always @ (posedge clk_5p33us or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_10p6us_50_50 <= 1'b1;
   else
      clk_10p6us_50_50 <= ~clk_10p6us_50_50;
end

always @ (posedge clk_10p6us or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_21p3us_50_50 <= 1'b1;
   else
      clk_21p3us_50_50 <= ~clk_21p3us_50_50;
end

always @ (posedge clk_21p3us or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_42p6us_50_50 <= 1'b1;
   else
      clk_42p6us_50_50 <= ~clk_42p6us_50_50;
end

always @ (posedge clk_42p6us or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_85p3us_50_50 <= 1'b1;
   else
      clk_85p3us_50_50 <= ~clk_85p3us_50_50;
end

always @ (posedge clk_85p3us or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_170p6us_50_50 <= 1'b1;
   else
      clk_170p6us_50_50 <= ~clk_170p6us_50_50;
end

always @ (posedge clk_170p6us or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_341p3us_50_50 <= 1'b1;
   else
      clk_341p3us_50_50 <= ~clk_341p3us_50_50;
end

always @ (posedge clk_341p3us or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_682p6us_50_50 <= 1'b1;
   else
      clk_682p6us_50_50 <= ~clk_682p6us_50_50;
end

always @ (posedge clk_682p6us or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_1p37ms_50_50 <= 1'b1;
   else
      clk_1p37ms_50_50 <= ~clk_1p37ms_50_50;
end

always @ (posedge clk_1p37ms or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_2p73ms_50_50 <= 1'b1;
   else
      clk_2p73ms_50_50 <= ~clk_2p73ms_50_50;
end

always @ (posedge clk_2p73ms or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_5p46ms_50_50 <= 1'b1;
   else
      clk_5p46ms_50_50 <= ~clk_5p46ms_50_50;
end

always @ (posedge clk_5p46ms or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_10p9ms_50_50 <= 1'b1;
   else
      clk_10p9ms_50_50 <= ~clk_10p9ms_50_50;
end

always @ (posedge clk_10p9ms or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_21p8ms_50_50 <= 1'b1;
   else
      clk_21p8ms_50_50 <= ~clk_21p8ms_50_50;
end

always @ (posedge clk_21p8ms or negedge vcore_rdy) begin
   if (!vcore_rdy)
      clk_43p7ms_50_50 <= 1'b1;
   else
      clk_43p7ms_50_50 <= ~clk_43p7ms_50_50;
end


/// ----------------------------------------------------------------------------
/// Ripple counter enables and CGG
/// ----------------------------------------------------------------------------
assign clk_166ns_en   = tb_fast_clk | (~clk_166ns_50_50);
assign clk_333ns_en   = tb_fast_clk | (~clk_333ns_50_50    & clk_166ns_en);
assign clk_666ns_en   = tb_fast_clk | (~clk_666ns_50_50    & clk_333ns_en);
assign clk_1p33us_en  = tb_fast_clk | (~clk_1p33us_50_50   & clk_666ns_en);
assign clk_2p66us_en  = tb_fast_clk | (~clk_2p66us_50_50   & clk_1p33us_en);
assign clk_5p33us_en  = tb_fast_clk | (~clk_5p33us_50_50   & clk_2p66us_en);
assign clk_10p6us_en  = tb_fast_clk | (~clk_10p6us_50_50   & clk_5p33us_en);
assign clk_21p3us_en  = tb_fast_clk | (~clk_21p3us_50_50   & clk_10p6us_en);
assign clk_42p6us_en  = tb_fast_clk | (~clk_42p6us_50_50   & clk_21p3us_en);
assign clk_85p3us_en  = tb_fast_clk | (~clk_85p3us_50_50   & clk_42p6us_en);
assign clk_170p6us_en = tb_fast_clk | (~clk_170p6us_50_50  & clk_85p3us_en);
assign clk_341p3us_en = tb_fast_clk | (~clk_341p3us_50_50 & clk_170p6us_en);
assign clk_682p6us_en = tb_fast_clk | (~clk_682p6us_50_50 & clk_341p3us_en);
assign clk_1p37ms_en  = tb_fast_clk | (~clk_1p37ms_50_50  & clk_682p6us_en);
assign clk_2p73ms_en  = tb_fast_clk | (~clk_2p73ms_50_50  & clk_1p37ms_en);
assign clk_5p46ms_en  = tb_fast_clk | (~clk_5p46ms_50_50  & clk_2p73ms_en);
assign clk_10p9ms_en  = tb_fast_clk | (~clk_10p9ms_50_50  & clk_5p46ms_en);
assign clk_21p8ms_en  = tb_fast_clk | (~clk_21p8ms_50_50  & clk_10p9ms_en);
assign clk_43p7ms_en  = tb_fast_clk | (~clk_43p7ms_50_50  & clk_21p8ms_en);

dig_cgc cgc_clk_166ns   ( .clkout( clk_166ns   ), .clkin( clk_12Mhz ), .en( clk_166ns_en   ), .se( scan_en ) );
dig_cgc cgc_clk_333ns   ( .clkout( clk_333ns   ), .clkin( clk_12Mhz ), .en( clk_333ns_en   ), .se( scan_en ) );
dig_cgc cgc_clk_666ns   ( .clkout( clk_666ns   ), .clkin( clk_12Mhz ), .en( clk_666ns_en   ), .se( scan_en ) );
dig_cgc cgc_clk_1p33us  ( .clkout( clk_1p33us  ), .clkin( clk_12Mhz ), .en( clk_1p33us_en  ), .se( scan_en ) );
dig_cgc cgc_clk_2p66us  ( .clkout( clk_2p66us  ), .clkin( clk_12Mhz ), .en( clk_2p66us_en  ), .se( scan_en ) );
dig_cgc cgc_clk_5p33us  ( .clkout( clk_5p33us  ), .clkin( clk_12Mhz ), .en( clk_5p33us_en  ), .se( scan_en ) );
dig_cgc cgc_clk_10p6us  ( .clkout( clk_10p6us  ), .clkin( clk_12Mhz ), .en( clk_10p6us_en  ), .se( scan_en ) );
dig_cgc cgc_clk_21p3us  ( .clkout( clk_21p3us  ), .clkin( clk_12Mhz ), .en( clk_21p3us_en  ), .se( scan_en ) );
dig_cgc cgc_clk_42p6us  ( .clkout( clk_42p6us  ), .clkin( clk_12Mhz ), .en( clk_42p6us_en  ), .se( scan_en ) );
dig_cgc cgc_clk_85p3us  ( .clkout( clk_85p3us  ), .clkin( clk_12Mhz ), .en( clk_85p3us_en  ), .se( scan_en ) );
dig_cgc cgc_clk_170p6us ( .clkout( clk_170p6us ), .clkin( clk_12Mhz ), .en( clk_170p6us_en ), .se( scan_en ) );
dig_cgc cgc_clk_341p3us ( .clkout( clk_341p3us ), .clkin( clk_12Mhz ), .en( clk_341p3us_en ), .se( scan_en ) );
dig_cgc cgc_clk_682p6us ( .clkout( clk_682p6us ), .clkin( clk_12Mhz ), .en( clk_682p6us_en ), .se( scan_en ) );
dig_cgc cgc_clk_1p37ms  ( .clkout( clk_1p37ms  ), .clkin( clk_12Mhz ), .en( clk_1p37ms_en  ), .se( scan_en ) );
dig_cgc cgc_clk_2p73ms  ( .clkout( clk_2p73ms  ), .clkin( clk_12Mhz ), .en( clk_2p73ms_en  ), .se( scan_en ) );
dig_cgc cgc_clk_5p46ms  ( .clkout( clk_5p46ms  ), .clkin( clk_12Mhz ), .en( clk_5p46ms_en  ), .se( scan_en ) );
dig_cgc cgc_clk_10p9ms  ( .clkout( clk_10p9ms  ), .clkin( clk_12Mhz ), .en( clk_10p9ms_en  ), .se( scan_en ) );
dig_cgc cgc_clk_21p8ms  ( .clkout( clk_21p8ms  ), .clkin( clk_12Mhz ), .en( clk_21p8ms_en  ), .se( scan_en ) );
dig_cgc cgc_clk_43p7ms  ( .clkout( clk_43p7ms  ), .clkin( clk_12Mhz ), .en( clk_43p7ms_en  ), .se( scan_en ) );

endmodule
