library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

library unisim;

entity ddr_clk_gen is

  port(
    rst: in std_logic;
    clkin : in std_logic;
    --
    logic_reset: out std_logic;

    clk: out std_logic;
    clkb: out std_logic
    );
end entity ddr_clk_gen;


architecture v0 of ddr_clk_gen is

  component dcm
    generic (
      CLKDV_DIVIDE : real := 2.0;
      CLKFX_DIVIDE : integer := 1;
      CLKFX_MULTIPLY : integer := 4;
      CLKIN_DIVIDE_BY_2 : boolean := false;
      CLKIN_PERIOD : real := 0.0;
      CLKOUT_PHASE_SHIFT : string := "NONE";
      CLK_FEEDBACK : string := "1X";
      DESKEW_ADJUST : string := "SYSTEM_SYNCHRONOUS";
      DFS_FREQUENCY_MODE : string := "LOW";
      DLL_FREQUENCY_MODE : string := "LOW";
      DSS_MODE : string := "NONE";
      DUTY_CYCLE_CORRECTION : boolean := true;
      FACTORY_JF : bit_vector := X"8080";
      PHASE_SHIFT : integer := 0;
      STARTUP_WAIT : boolean := false
      );
    port (
      CLKFB    : in     std_ulogic                    := '0';
      CLKIN    : in     std_ulogic                    := '0';
      DSSEN    : in     std_ulogic                    := '0';
      PSCLK    : in     std_ulogic                    := '0';
      PSEN     : in     std_ulogic                    := '0';
      PSINCDEC : in     std_ulogic                    := '0';
      RST      : in     std_ulogic                    := '0';
      CLK0     : out    std_ulogic                    := '0';
      CLK180   : out    std_ulogic                    := '0';
      CLK270   : out    std_ulogic                    := '0';
      CLK2X    : out    std_ulogic                    := '0';
      CLK2X180 : out    std_ulogic                    := '0';
      CLK90    : out    std_ulogic                    := '0';
      CLKDV    : out    std_ulogic                    := '0';
      CLKFX    : out    std_ulogic                    := '0';
      CLKFX180 : out    std_ulogic                    := '0';
      LOCKED   : out    std_ulogic                    := '0';
      PSDONE   : out    std_ulogic                    := '0';
      STATUS   : out    std_logic_vector (7 downto 0) := "00000000"
      );
  end component;

  component bufg 
    port (
      i : in     std_ulogic;
      o : out    std_ulogic
      );
  end component;
  


  -- pragma synthesis_off
  for all : bufg use entity unisim.bufg;
  for all : dcm use entity unisim.dcm;
  -- pragma synthesis_on

  

  signal int_dcm_clk0: std_logic;
  signal int_dcm_clk0_bufgd:std_logic;
  signal int_dcm_clk180: std_logic;
  signal int_dcm_clk180_bufgd: std_logic;

  signal int_logic_rst_count: std_logic_vector(15 downto 0);
  constant reset_len:std_logic_vector(15 downto 0):=conv_std_logic_vector(1000, 16);
  signal int_locked: std_logic;
  signal int_logic_rst: std_logic;
begin

  logic_reset<=int_logic_rst;
  
  gen_logic_rst: process(rst, clkin)
  begin 
    if(rst='1')then
      int_logic_rst_count<=(others=>'0');
      int_logic_rst<='1';
    elsif(clkin'event and clkin='1')then     
      if(int_locked='0')then
        int_logic_rst_count<=(others=>'0');       
        int_logic_rst<='1';
      else 
        if(int_logic_rst_count<reset_len)then 
          int_logic_rst_count<=int_logic_rst_count+1;
          int_logic_rst<='1';
        else
          int_logic_rst<='0';
        end if;
      end if;
    end if;
  end process gen_logic_rst;

  
  u_dcm0 : DCM
    generic map (      
      CLKDV_DIVIDE => 2.0,
      CLKFX_DIVIDE => 1,
      CLKFX_MULTIPLY => 4,
      CLKIN_DIVIDE_BY_2 => FALSE,
      CLKIN_PERIOD => 25.0,
      CLKOUT_PHASE_SHIFT => "NONE",
      CLK_FEEDBACK => "1X",
      DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS",
      DFS_FREQUENCY_MODE => "LOW",
      DLL_FREQUENCY_MODE => "LOW",
      DSS_MODE    => "NONE",
      DUTY_CYCLE_CORRECTION=> true,
      FACTORY_JF => X"C080",
      PHASE_SHIFT => 0,
      STARTUP_WAIT => false
      )
    port map (
      CLK0     => int_dcm_clk0,
      CLK180   => int_dcm_clk180,
      CLK270   => open,
      CLK2X    => open,
      CLK2X180 => open,
      CLK90    => open,
      CLKDV    => open,
      CLKFX    => open,
      CLKFX180 => open,
      LOCKED   => int_locked,
      PSDONE   => open,
      STATUS   => open,
      CLKFB    => int_dcm_clk0_bufgd,
      CLKIN    => clkin,
      DSSEN    => open,
      PSCLK    => open,
      PSEN     => open,
      PSINCDEC => open,
      RST      => rst
      );

  
  u_clk0_buf:bufg
    port map(
      o => int_dcm_clk0_bufgd,
      i => int_dcm_clk0
      );

  
  u_clk180_buf:bufg
    port map(
      o => int_dcm_clk180_bufgd,
      i => int_dcm_clk180
      );

  clk<=int_dcm_clk0_bufgd;
  clkb<=int_dcm_clk180_bufgd;

end architecture v0;
