/*
 Global clocks, DCMs, buffers

 Copyright (c) 2008 Dimtel, Inc., All Rights Reserved

 $Id: clk_ctrl.v,v 1.4 2012/11/12 10:39:19 dim Exp $
 $Date: 2012/11/12 10:39:19 $
 $Author: dim $
 $Revision: 1.4 $
 $Log: clk_ctrl.v,v $
 Revision 1.4  2012/11/12 10:39:19  dim
 Optimized for 8.64 ns

 Revision 1.3  2012/11/11 08:31:49  dim
 Optimized to meet 9 ns timing

 Revision 1.2  2012/11/11 06:03:30  dim
 Updates and fixes in 2009-2012 timeframe

 Revision 1.1.1.1  2009/06/02 20:26:02  dim
 Initial import


*/

module clk_ctrl(
  // ADC and fast processing clocks
  input		DSPCLK,
  input		clk_rst,
  output	clk_raw,
  output	clk,
  output	clk180,
  output	clk2,
  output	usbclkfx,
  output	clk_lock,
  output [7:0]  stat,
  input		psclk,
  input		psen,
  input		psincdec,
  output	psdone,
  
  // Local bus clock
  input		usbclk_in,
  output	usbclk,
  output	usbclk_lock
);
  wire clk_dcm, clk180_dcm, clk2_dcm, usbclk2x_dcm, usbclk_bufg;

  // Receive the ADC clock
  IBUFG aclk_ibuf(.I(DSPCLK), .O(clk_raw));
  
  DCM #(.CLKOUT_PHASE_SHIFT("variable"),
        .PHASE_SHIFT(0),
        .CLKDV_DIVIDE(2),
        .DLL_FREQUENCY_MODE("low"))
      adc_dcm (.CLK0 (clk_dcm),
               .CLK180 (clk180_dcm),
               .CLK270 (),
               .CLK2X (),
               .CLK2X180 (),
               .CLK90 (),
               .CLKDV (clk2_dcm),
               .CLKFX (),
               .CLKFX180 (),
               .LOCKED (clk_lock),
               .PSDONE (psdone),
               .STATUS (stat),
               .CLKFB (clk),
               .CLKIN (clk_raw),
               .DSSEN (1'b0),
               .PSCLK (psclk),
               .PSEN (psen),
               .PSINCDEC (psincdec),
               .RST (clk_rst));
             
  BUFG clk_buf   (.O(clk),    .I(clk_dcm));
  BUFG clk180_buf(.O(clk180), .I(clk180_dcm));
  BUFG clk2_buf(.O(clk2), .I(clk2_dcm));

  // Receive the local bus clock
  DCM dcm_usbclk
              (.CLK0 (usbclk_dcm),
               .CLK180 (),
               .CLK270 (),
               .CLK2X (usbclkfx_dcm),
               .CLK2X180 (),
               .CLK90 (),
               .CLKDV (),
               .CLKFX (),
               .CLKFX180 (),
               .LOCKED (usbclk_lock),
               .PSDONE (),
               .STATUS (),
               .CLKFB (usbclk),
               .CLKIN (usbclk_bufg),
               .DSSEN (1'b0),
               .PSCLK (1'b0),
               .PSEN (1'b0),
               .PSINCDEC (1'b0),
               .RST (1'b0));
  defparam dcm_usbclk.CLKOUT_PHASE_SHIFT="fixed";

  IBUFG usbclk_ibufg(.O(usbclk_bufg), .I(usbclk_in));
  BUFG usbclk_buf(.O(usbclk), .I(usbclk_dcm));
  BUFG usbclkfx_buf(.O(usbclkfx), .I(usbclkfx_dcm));

endmodule // clk_ctrl
